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));
}
}
}