C# 三重加密和解密会产生奇怪的结果

C# 三重加密和解密会产生奇怪的结果,c#,.net,cryptography,C#,.net,Cryptography,我有一个TripleDESCng的工作实现(针对一些测试向量进行了测试),但发生了以下情况: 当我加密纯文本这是一个示例消息(24字节,因此它将是3个块)(十六进制,因为它是54686973206973206120736616D706C65206D65733616765)和一个示例密钥,我得到E81F113DD7C5D965E082F3D42EC1E2CA39BCDBCC0A2BD9。但是,当我用相同的示例密钥解密时,我得到5468697320697320612073616D706C650000

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

当我加密纯文本
这是一个示例消息
(24字节,因此它将是3个块)(十六进制,因为它是
54686973206973206120736616D706C65206D65733616765
)和一个示例密钥,我得到
E81F113DD7C5D965E082F3D42EC1E2CA39BCDBCC0A2BD9。但是,当我用相同的示例密钥解密时,我得到
5468697320697320612073616D706C650000000000000000
,当转换回ASCII时,它是:

这是一个示例

除了我的代码之外,还有什么原因可以解释为什么会这样?为了加密和解密,我使用24字节密钥(ECB模式)

编辑:

对于几乎所有的模式1,您应该确保数据的最后一部分被推送,而不是
TransformBlock
2,以确保它知道不再有数据到来,并确保最后的数据块被刷新/写入

一般来说,假设输出大小与输入大小匹配是不好的

该模式没有问题,无论哪种方式,IV都设置为0

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


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

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


3你选择了一个过时的加密算法,将它与一个过时的操作模式配对,我上面引用的你的话意味着你不理解模式。加在一起,我建议您目前不适合编写使用加密的代码。NET类可以使编写加密代码看起来很容易,但您仍然需要了解如何在使用它们时做出正确的选择。最好在编写代码之前花更多的时间研究这些东西。

我认为您的问题在于您正在使用的加密/解密程序的方法: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));
        }
    }
}

默认模式是CBC,而不是EBC。既然您没有明确设置
模式
,为什么您认为这是EBC?再加上2018年。出于历史兴趣,你为什么要编写使用过时密码和过时模式的新代码?@Damien_不相信模式不是问题,IV设置为0s,我很清楚默认模式是CBC。很抱歉,但是你的建议似乎是基于对我的知识和算法选择的模糊假设,顺便说一句,我故意忽略了这一点,因为我有自己的原因(别担心,这段代码不应该到达生产阶段),实际问题确实出在最后一个块上,我同意我应该仔细研究一下,谢谢
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));
        }
    }
}