我想计算MAC(消息验证码) CBC 芯片(Ansi x9.9),我找到了一个基于循环计算 MAC 的示例,在每一轮中,加密的结果必须与下一轮纯文本块和结果应该被加密以用于下一步,这个循环重复4次,直到最后一个加密值必须作为MAC返回。
加密密钥 = 0123456789abcdef
文本是“7654321 Now is the time for”的ASCII码。
文本 = 37363534333231204e6f77206873207468652074696d6520666f7220
时间---纯文本---------------DES输入块--------DES输出块
1 ---- 3736353433323120 -------- 3736353433323120 -------- 21fb193693a16c28
2 ---- 4e6f772068732074 -------- 6f946e16fad24c5c -------- 6c463f0cb7167a6f
3 ---- 68652074696d6520 -------- 04231f78de7b1f4f -------- 956ee891e889d91e
4 ---- 666f722000000000 -------- f3019ab1e889d91e -------- f1d30f6849312ca4
我试图实现这个示例。在第一步,我得到了与样本相同的结果,但对于下一步,我的 Des 加密函数返回不同的结果作为样本的第二步。我使用硬件设备加密每个 Des 输入块,它返回与样本返回相同的 DES 输出块。要么我在这里找到了另一个 DES 实现示例,它也重新输入了正确的加密。但是我在 msdn 上使用 microsft 示例的应用程序返回的步骤 2,3 和 4 的结果不正确,但步骤 1 除外。这是我的代码:
    public  byte[] EncryptPart(byte[] toEncrypt, byte[] Key, byte[] IV)
    {
        try
        {
            MemoryStream mStream = new MemoryStream();
            DES DESalg = DES.Create();
            DESalg.Mode = CipherMode.CBC;
            DESalg.Padding = PaddingMode.None;
            CryptoStream cStream = new CryptoStream(mStream,
                DESalg.CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);
            cStream.Write(toEncrypt, 0, toEncrypt.Length);
            cStream.FlushFinalBlock();
            byte[] ret = mStream.ToArray();
            cStream.Close();
            mStream.Close();
            return ret;
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
            return null;
        }
    }
在这里我使用了该功能
        var IV = new byte[8];//empty byte array
        var key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
        var result = new byte[8];
        int LoopCount = data.Length / 8;
        for (int i = 0; i < LoopCount; i++)
        {
            byte[] Part= new byte[8];
            Array.Copy(data, i * 8, Part, 0, 8);
            Part = XorArray(Part, result);
            result = EncryptPart(Part, key, IV);
        }
        int remain=data.Length % 8;
        if (remain != 0)
        {
            byte[] LastPart = new byte[8];//
            Array.Copy(data, data.Length - remain, LastPart, 0, remain);
            LastPart=XorArray(LastPart, result);
            result = EncryptPart(LastPart, key, IV); 
        }