C# 如何使用DES实现CBC-MAC?

C# 如何使用DES实现CBC-MAC?,c#,encryption,cryptography,des,cbc-mac,C#,Encryption,Cryptography,Des,Cbc Mac,我应该在C#中实现一个MAC-CBC生成方法,并提供一些关于加密算法的信息。以下是我所拥有的: 我应该用DES 键是byte[]{11,11,11,11,11,11} 数据(16字节)应按8字节部分加密。前8个字节使用实例向量=新字节[8]加密(8个字节,值为0)。(CBC?) 加密值的最后8个字节应转换为十六进制字符串。这是我应该发送的结果 有了这些信息,我实现了以下方法: public static string Encrypt(byte[] data) { var IV = n

我应该在C#中实现一个MAC-CBC生成方法,并提供一些关于加密算法的信息。以下是我所拥有的:

  • 我应该用DES
  • 键是
    byte[]{11,11,11,11,11,11}
  • 数据(16字节)应按8字节部分加密。前8个字节使用
    实例向量=新字节[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,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需要零初始化向量。明确指定IV更好:

var IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };  
您说您的密钥是
byte[]{11,11,11,11,11,11}
这些字节是十六进制还是10进制?您可能想试试:

var key = new byte[] { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
看看效果是否更好。

该项目有一个通用的MAC-CBC实现,可以在任何对称算法上运行——即使它在内部仅用于实现MACTripleDES


您可以找到MIT.X11许可的源代码。按原样使用或与您自己的代码进行比较。

谢谢。虽然我没有得到正确的结果。但这是我没有尝试过的一种方法。@Kaymar:再看看这个问题,您是否在处理纯文本,
{0,6,4,1,6,4,1,7,E,E,F,F,F,F,F,F,B}
是十六进制还是十进制?你确定这是正确的明文,所有值都在16以下吗?这个bytearray是通过使用自定义算法将PAN number与PIN code进行XORing来计算的。这个bytearray是银行提供给我的。我确信
{0,6,4,1,…}
是正确的数组。已使用
Encoding.ASCII.GetBytes
获取字符串的字节数组:"06416417EEFFFFBB`。您建议我使用另一种方法将它们插入字节数组吗?您的字符串在我看来像十六进制。您应该尝试将其作为8个十六进制字节,而不是16个ASCII字节/半字节。对于应用了填充的消息,CBC-MAC是不安全的。这意味着消息必须是DES块的大小,否则您会丢失相当多的秒urity。您应该使用CMAC或HMAC instaed。CMAC是一种正确的CBC-MAC。DES在几年前因为不安全而被弃用。您可能应该切换到现代分组密码,如3密钥三重DES、AES或Cameilla。