2011-10-03 129 views
2

我應該在C#中實現MAC-CBC生成方法,並提供有關密碼算法的一些信息。這是我有:如何使用DES實現CBC-MAC?

  • 我應該使用DES。
  • 關鍵是byte[] {11, 11, 11, 11, 11, 11, 11, 11}
  • 數據(16字節)應以8字節部分加密。前8個字節使用Instance Vector = new byte[8](具有0值的8個字節)進行加密。 (CBC?)
  • 最後8個字節的加密值應該轉換爲十六進制字符串。這是我應該發送的結果。

利用該信息,我已實現了以下方法:

public static string Encrypt(byte[] data) 
{ 
    var IV = new byte[8]; 
    var key = new byte[] { 11, 11, 11, 11, 11, 11, 11, 11 }; 
    var result = new byte[16]; 

    // Create DES and encrypt. 
    var des = DES.Create(); 
    des.Key = key; 
    des.IV = IV; 
    des.Padding = PaddingMode.None; 
    des.Mode = CipherMode.CBC; 
    ICryptoTransform cryptoTransform = des.CreateEncryptor(key, IV); 
    cryptoTransform.TransformBlock(data, 0, 16, result, 0); 

    // Get the last eight bytes of the encrypted data. 
    var lastEightBytes = new byte[8]; 
    Array.Copy(result, 8, lastEightBytes, 0, 8); 

    // Convert to hex. 
    var hexResult = string.Empty; 
    foreach (byte ascii in lastEightBytes) 
    { 
     int n = (int)ascii; 
     hexResult += n.ToString("X").PadLeft(2, '0'); 
    } 

    return hexResult; 
} 

他們提供我將樣品原始數據是:input=byte[] {0, 6, 4, 1, 6, 4, 1, 7, E, E, F, F, F, F, B, B)應返回的值的輸出:A7CBFB3C730B059C。這意味着加密數據的最後八個字節應該是:byte[] {167, 203, 251, 60, 115, 11, 05, 156}

但不幸的是,使用上述方法,我得到:32D91200D0007632。這意味着我的加密數據不正確。 (我方法生成的加密值的最後八個字節是byte[] {50, 207, 18, 0, 208, 0, 118, 50})。

有沒有什麼辦法可以找到我應該做些什麼來達到A7CB ......?難道我做錯了什麼?

+0

對於應用了填充的消息,CBC-MAC不安全。這意味着一條消息必須是DES塊的大小,否則你失去了相當的安全性。你應該使用CMAC或HMAC instaed。 CMAC是CBC-MAC正確的。 DES在幾年前已經被棄用,因爲它不安全。您應該切換到現代的分組密碼,例如3鍵Triple DES,AES或Cameilla。 – jww

回答

4

CBC-MAC需要一個零初始化向量。好多明確指定的IV:

var IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }; 

你說你的關鍵是byte[] { 11, 11, 11, 11, 11, 11, 11, 11 }是十六進制或基10這些字節?你可能想嘗試:

var key = new byte[] { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 }; 

看看是否更好。

+0

謝謝。雖然我無法得到正確的結果。但這是我沒有嘗試過的一種方式。 – Kamyar

+0

@Kaymar:再看看這個問題,你是否在處理明文'{0,6,4,1,6,4,1,7,E,E,F,F,F,F,B,B} '十六進制或十進制?你確定這是正確的明文,所有值都低於16嗎? – rossum

+0

該字節數組通過使用自定義算法將PAN編號與PIN碼異或來計算。這個字節陣是銀行提供給我的。我確定'{0,6,4,1,...}是正確的數組。並使用'Encoding.ASCII.GetBytes'獲取字符串的字節數組:「06416417EEFFFFBB」。你是否建議我應該用另一種方法將它們轉換爲字節數組? – Kamyar

2

Mono項目有一個通用的MAC-CBC的實現,應該在任何SymmetricAlgorithm工作 - 即使它的使用,在內部,只有實現MACTripleDES

你可以找到MIT.X11許可的源代碼here。按原樣使用或將其與您自己的代碼進行比較。