TripleDES加密和解密给出奇怪的结果

时间:2018-07-31 12:04:22

标签: c# .net cryptography

我有一个TripleDESCng的有效实现(已针对某些测试向量进行了测试),但是会发生以下情况:

当我使用示例密钥对纯文本This is a sample message(24个字节,因此将是3个块)进行加密(十六进制为5468697320697320612073616D706C65206D657373616765)时,我得到了E81F113DD7C5D965E082F3D42EC1E2CA39BCDBCCBC0A2BD9。但是,当我使用相同的示例密钥对此进行解密时,会得到5468697320697320612073616D706C650000000000000000,当转换回ASCII时,它是:

This is a sample

除了我的代码外,还有其他原因会导致这种行为吗?为了加密和解密,我使用24字节密钥(ECB模式)。

编辑:

using (var tripleDES = new TripleDESCryptoServiceProvider())
{
   byte[] data = ASCIIEncoding.ASCII.GetBytes("This is a sample message");
   Console.WriteLine(BitConverter.ToString(data));
   tripleDES.IV = new byte[tripleDES.BlockSize / 8];
   var encryptor = tripleDES.CreateEncryptor();
   byte[] result = new byte[data.Length];
   encryptor.TransformBlock(data, 0, data.Length, result, 0);
   var decryptor = tripleDES.CreateDecryptor();
   byte[] result2 = new byte[result.Length];
   decryptor.TransformBlock(result, 0, result.Length, result2, 0);
   Console.WriteLine(BitConverter.ToString(result2));
}
Console.ReadLine();

2 个答案:

答案 0 :(得分:2)

在几乎所有模式下 1 ,您都应确保数据的最后部分通过TransformFinalBlock而不是TransformBlock 2 ,以确保它知道不再有数据来,并确保清除/写入了最后的块。

通常,这是一种不好的形式,假设输出大小将与输入大小匹配。

  

模式不是问题,IV都可以设置为0s

是的,这意味着 first 块不受您选择的模式的影响。但是所有后续块都将是,因为它们将使用链接模式和前一个块IV而不是 not 。因此,如果您想要 ECB(不应该 3 ),则需要显式设置该模式。


1 您的代码使用的是CBC,而不是您在叙述中声称的EBC。 CBC是.NET加密类的默认模式。

2 使用第二种方法时,请注意它的返回值,如mjwills所评论。

3 您选择了一种过时的加密算法,将其与一种过时的操作模式配对,而我在上面引用的词表示您不了解模式。加在一起,我会建议,您不适合编写当前使用加密的代码。 .NET类可以使编写加密代码看起来很容易,但是您仍然必须了解如何在使用它们时做出正确的选择。最好在编写代码之前花更多时间在研究上。

答案 1 :(得分:1)

我认为您的问题出在您使用的加密器/解密器的方法中:当您要加密多个块时,可以设想使用TransformBlock方法来转换一个块。

在您的代码中不是这样,您要转换单个块,因此应该改用TransformFinalBlock方法。顺便说一句,我冒犯了使您的样本可构建的自由。

using System;
using System.Text;

namespace Tests
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Security.Cryptography.TripleDESCryptoServiceProvider tripleDES = new System.Security.Cryptography.TripleDESCryptoServiceProvider();
            byte[] data = Encoding.UTF8.GetBytes("This is a sample message");
            byte[] key = Encoding.UTF8.GetBytes("NOSTROMOHASSOMEGODPOWERS");
            tripleDES.Key = key;
            tripleDES.IV = new byte[tripleDES.BlockSize / 8];
            var encryptor = tripleDES.CreateEncryptor();
            byte[] result = new byte[data.Length];
            result = encryptor.TransformFinalBlock(data, 0, data.Length);
            string res = BitConverter.ToString(result).Replace("-","");
            Console.WriteLine(BitConverter.ToString(result).Replace("-",""));

            byte[] data2 = result;
            tripleDES.Key = key;
            tripleDES.IV = new byte[tripleDES.BlockSize / 8];
            var decryptor = tripleDES.CreateDecryptor();
            byte[] result2 = new byte[data2.Length];
            result2 = decryptor.TransformFinalBlock(data2, 0, data2.Length);
            Console.WriteLine(Encoding.UTF8.GetString(result2));
        }
    }
}