没有初始化向量的C#TripleDES提供程序?

Ric*_*ahl 8 c# tripledes

我有一组用来自远程系统的TripleDES编码的加密文档.我需要解码C#中的数据,我无法控制密钥或编码算法.我所拥有的只是密钥和模式(CBC)以及位于文件中的数据.

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);
Run Code Online (Sandbox Code Playgroud)

这与错误的数据完全失败.如果我切换到TransformBlock,代码至少会运行但只产生乱码:

   byte[] output = new byte[10000];
   var count = decryptor.TransformBlock(encoded, 0, encoded.Length, output, 0);
Run Code Online (Sandbox Code Playgroud)

所以问题是:

  • 如果我只有一个键是必需的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();
Run Code Online (Sandbox Code Playgroud)

我们的关键是使用适当的CipherMode和Padding.修复填充使TransformFinalBlock()工作没有错误数据错误.修复CipherMode使数据正确未加密.

故事的道德:在CipherMode.ECB模式中,至少有一个初始化向量,您不需要提供初始化向量.如果没有提供IV,提供者将自动生成一个,但解密仍然有效(至少对于ECB).

最后,确保您拥有加密数据的提供商的所有信息是非常重要的.

San*_*nen 9

试着回答每一点:

  • CBC模式下需要初始化矢量.它不需要是秘密(与密钥不同),因此它应该从远程系统发送.
  • 因为你需要IV,所以null不是正确的.
  • 填充模式.您需要知道使用哪种填充模式.
  • TransformFinalBlock可能会失败,因为填充模式是错误的.

编辑

ECB(电子代码簿)和CBC(密码块链接)之间的区别如下:

ECB模式

CBC模式

如您所见,在ECB模式下不使用IV.所以,即使你提供一个,它也会被忽略.