我有一个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();
答案 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));
}
}
}