我有一组使用TripleDES编码的加密文档,来自远程系统。我需要在C#中解码数据,但我无法控制密钥或编码算法。我只有密钥和模式(CBC),以及位于文件中的数据。
TripleDESCryptoServiceProvider很容易使用,但是我不知道如何在没有初始化向量的情况下使用Decryptor。
我们有24字节(192位)密钥来解密,但没有其他信息。
在我们的案例中,关键是使用适当的CipherMode和Padding。修复填充使TransformFinalBlock()能够正常工作,而不会出现“Bad Data”错误。修复CipherMode可以正确地解密数据。
故事的寓意:在CipherMode.ECB模式下,至少不需要提供初始化向量。如果没有提供IV,则提供程序将自动生成一个,但解密仍然有效(至少在ECB模式下)。
最重要的是确保您从加密数据的提供程序那里获得了所有信息。
TripleDESCryptoServiceProvider很容易使用,但是我不知道如何在没有初始化向量的情况下使用Decryptor。
我们有24字节(192位)密钥来解密,但没有其他信息。
string key = "1468697320656E6372797174696F6E206973737265206933";
byte[] keyData = ParseHex(key); // key is OK at 24 bytes
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Mode = CipherMode.CBC;
des.GenerateIV();
var decryptor = des.CreateDecryptor(keyData,null); // des.IV
var encoded = File.ReadAllBytes(@"..\..\..\..\test.tdes");
byte[] output = decryptor.TransformFinalBlock(encoded, 0, encoded.Length);
这会直接导致 Bad data 错误。如果我切换到 TransformBlock,代码至少可以运行,但是生成的只是一些无意义的字符:
byte[] output = new byte[10000];
var count = decryptor.TransformBlock(encoded, 0, encoded.Length, output, 0);
所以问题是:
- 如果我只有一个密钥,是否需要InitializationVector?
- 如果不需要,传递null是正确的吗?
- 除了密钥和模式之外,我还需要设置什么?
- 为什么TransformBlock至少可以工作,而TransformFinalBlock会失败?
更新 - 找到了问题
事实证明,解码问题不是由缺少初始化向量引起的,而是由加密数据提供者提供的错误信息引起的。更新后的工作代码如下:
// Read the test data
byte[] encoded = File.ReadAllBytes(@"..\..\..\..\test.tdes");
// Get the key into a byte array
string key = "1468697320656E6372797174696F6E206973737265206933";
byte[] keyData = ParseHex(key);
TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.Mode = CipherMode.ECB; // Make sure this is correct!!!
des.Padding = PaddingMode.Zeros; // Make sure this is correct!!!
des.Key = keyData;
var decryptor = des.CreateDecryptor();
byte[] output = decryptor.TransformFinalBlock(encoded, 0, encoded.Length);
string dataString = Encoding.Default.GetString(encoded);
Console.WriteLine(dataString);
Console.WriteLine("\r\n\r\nDecoded:");
string result = Encoding.Default.GetString(output);
Console.WriteLine(result);
Console.Read();
在我们的案例中,关键是使用适当的CipherMode和Padding。修复填充使TransformFinalBlock()能够正常工作,而不会出现“Bad Data”错误。修复CipherMode可以正确地解密数据。
故事的寓意:在CipherMode.ECB模式下,至少不需要提供初始化向量。如果没有提供IV,则提供程序将自动生成一个,但解密仍然有效(至少在ECB模式下)。
最重要的是确保您从加密数据的提供程序那里获得了所有信息。