如何使用 DES 实现 CBC-MAC?
Posted
技术标签:
【中文标题】如何使用 DES 实现 CBC-MAC?【英文标题】:How can I implement CBC-MAC with DES? 【发布时间】:2011-10-03 07:11:06 【问题描述】:我应该在 C# 中实现一个 MAC-CBC 生成方法,其中包含一些关于加密算法的信息。这是我所拥有的:
我应该使用 DES。 密钥是byte[] 11, 11, 11, 11, 11, 11, 11, 11
数据(16 字节)应以 8 字节部分加密。前 8 个字节使用 Instance Vector = new byte[8]
加密(8 个字节,值为 0)。 (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...?我做错了吗?
【问题讨论】:
CBC-MAC 对于应用了填充的消息是不安全的。这意味着消息必须是 DES 块的大小,否则您已经失去了相当多的安全性。您应该使用 CMAC 或 HMAC。 CMAC 是正确的 CBC-MAC。 DES 几年前就被弃用了,因为它不安全。您可能应该改用现代分组密码,例如 3-key Triple DES、AES 或 Cameilla。 【参考方案1】: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 ;
看看是否效果更好。
【讨论】:
谢谢。虽然我无法得到正确的结果。但这是我没有尝试过的一种方法。 @Kaymar:再看看这个问题,你是把纯文本 0, 6, 4, 1, 6, 4, 1, 7, E, E, F, F, F, F, B, B
当作十六进制还是十进制?你确定这是正确的明文,所有值都低于 16?
这个字节数组是通过使用自定义算法将 PAN 号码与 PIN 码进行异或运算来计算的。这个字节数组是银行提供给我的。我确定0, 6, 4, 1, ...
是正确的数组。并使用Encoding.ASCII.GetBytes
获取字符串的字节数组:“06416417EEFFFFBB`。您是否建议我应该使用另一种方法将它们转换为字节数组?
你的字符串在我看来像十六进制。您应该尝试 8 个十六进制字节,而不是 16 个 ASCII 字节/半字节。【参考方案2】:
Mono 项目有一个通用的 MAC-CBC 实现,它应该适用于任何 SymmetricAlgorithm - 即使它在内部被用于实现 MACTripleDES。 p>
您可以找到 MIT.X11 许可源代码here。 按原样使用或将其与您自己的代码进行比较。
【讨论】:
以上是关于如何使用 DES 实现 CBC-MAC?的主要内容,如果未能解决你的问题,请参考以下文章
如何在netbeans java中使用充气城堡(DES)加密和解密文件?