2011-10-03 128 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。按原样使用或将其与您自己的代码进行比较。