【问题标题】:Two methods for Des Cryptography returns two different result?Des Cryptography 的两种方法返回两个不同的结果?
【发布时间】:2013-11-08 11:20:08
【问题描述】:

我想计算 MAC(Message Authentication Code) CBC Chiper(Ansi x9.9),我找到了一个基于循环计算 MAC 的示例,在每一轮加密的结果必须与下一轮纯文本块进行异或,结果应加密以用于下一步,此循环重复 4 次,直到最后一个加密值必须作为 MAC 返回。

加密密钥 = 0123456789abcdef

文本是“7654321 Now is 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 实现示例here,它也返回了正确的加密。但是我在 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); 
        }

【问题讨论】:

  • 请使用内置的 HMAC 函数而不是这个。

标签: c# encryption cryptography des 3des


【解决方案1】:

您应该重复使用密码,而不是每次都使用密钥和 IV 重新初始化它。

调用代码:

var IV = new byte[8];//empty byte array
var key = new byte[] { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };

var data = Encoding.ASCII.GetBytes("7654321 Now is the time for ");

DES DESalg = DES.Create();
DESalg.Mode = CipherMode.CBC;
DESalg.Padding = PaddingMode.None;
ICryptoTransform crypt = DESalg.CreateEncryptor(key, IV);


var result = new byte[8];
int LoopCount = data.Length / 8;
for (int i = 0; i < LoopCount; i++)
{
    Console.WriteLine("=============Round {0}==============", i + 1);
    byte[] part = new byte[8];

    Array.Copy(data, i * 8, part, 0, 8);
    Console.WriteLine("Plain text : {0}", ByteArrayToString(part));
    part = XorArray(part, result);
    Console.WriteLine("DES INPUT  : {0}", ByteArrayToString(part));
    result = EncryptPart(crypt, part);

}
int remain = data.Length % 8;
if (remain != 0)
{
    Console.WriteLine("===========Final Round==============");
    byte[] LastPart = new byte[8];//
    Array.Copy(data, data.Length - remain, LastPart, 0, remain);
    Console.WriteLine("Plain text : " + ByteArrayToString(LastPart));
    LastPart = XorArray(LastPart, result);
    Console.WriteLine("DES INPUT  : " + ByteArrayToString(LastPart));
    result = EncryptPart(crypt, LastPart);
}

Console.WriteLine("Result: {0}", ByteArrayToString(result));

以及修改后的Encrypt部分方法:

public static byte[] EncryptPart(ICryptoTransform crypt, byte[] toEncrypt)
{
    try
    {

        MemoryStream mStream = new MemoryStream();

        CryptoStream cStream = new CryptoStream(mStream,
            crypt,
            CryptoStreamMode.Write);
        cStream.Write(toEncrypt, 0, toEncrypt.Length);
        cStream.FlushFinalBlock();
        byte[] ret = mStream.ToArray();
        cStream.Close();
        mStream.Close();

        Console.WriteLine("DES OUTPUT : " + ByteArrayToString(ret));
        return ret;
    }

    catch (CryptographicException e)
    {
        Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
        return null;
    }
}

结果:

=============Round 1============== 
Plain text : 3736353433323120 
DES INPUT  : 3736353433323120 
DES OUTPUT : 21fb193693a16c28
=============Round 2============== 
Plain text : 4e6f772069732074
DES INPUT  : 6f946e16fad24c5c 
DES OUTPUT : 6c463f0cb7167a6f
=============Round 3============== 
Plain text : 68652074696d6520 
DES INPUT  : 04231f78de7b1f4f 
DES OUTPUT : 956ee891e889d91e
===========Final Round============ 
Plain text : 666f722000000000 
DES INPUT  : f3019ab1e889d91e 
DES OUTPUT : f1d30f6849312ca4 
Result: f1d30f6849312ca4

这些值与您指定的值以及此 specification 中的值匹配

【讨论】:

  • 感谢sga101的回复。您的代码返回的结果与我的代码返回的结果相同。我发现样本返回了我们想要的不正确的 XOR 结果。 XOR 结果必须为 6f946e16fbd24c5c,而步骤 2 的样本结果为 6f946e16fad24c5c。
  • 我在我发布的代码中添加了一些打印语句,以便您可以看到每个阶段的结果。我认为它们与您提供的值相匹配。
  • 感谢Sga101的回复。您所做的所有路径都是正确的。我终于发现样本给我的输入数组字节并且我用它作为输入文本字节数组是不正确的。我看到你使用了这个代码:“var data = Encoding.ASCII.GetBytes("7654321 Now is the time for ");"此代码返回不同的字节数组作为示例 birgs:Text = 37363534333231204e6f77206873207468652074696d6520666f7220
  • 不同之处在于基于示例编码的第 2 轮纯文本是:4e6f772068732074,而您所做的正确转换是:4e6f772069732074 –
【解决方案2】:

错误的根本原因来自 FIPS 113 文档提供的十六进制字符串。

文本:“7654321 现在是时候”
十六进制(错误):“37363534333231204e6f77206873207468652074696d6520666f7220”
十六进制(正确):“37363534333231204e6f77206973207468652074696d6520666f7220”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多