【问题标题】:C# TripleDES Provider without an Initialization Vector?没有初始化向量的 C# TripleDES 提供程序?
【发布时间】:2012-09-20 23:07:51
【问题描述】:

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

TripleDESCryptoServiceProvider 很容易使用,但我不知道如何在没有初始化向量的情况下使用解密器。

我们有一个 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);

这会因错误数据而彻底失败。如果我切换到 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)。

最后,确保您从加密数据的提供商那里获得所有信息至关重要。

【问题讨论】:

  • 因为它确实是ECB模式,所以不需要IV,即使你提供了它也不会使用。

标签: c# tripledes


【解决方案1】:

尝试回答每一点:

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

编辑

ECB(Electronic Code Book)和CBC(Cipher Block Chaining)的区别如下:

如您所见,在 ECB 模式下没有使用 IV。因此,即使您提供一个,它也会被忽略。

【讨论】:

  • 萨尼谢谢!你在这里为我指明了正确的方向。填充可以消除不良数据问题(零)。我还开始尝试与提供商所说的不同的密码模式,我发现 ECB 有效。废话,因为提供商给了我们不正确的信息:-)
  • 很好,你解决了它。正如您在编辑中所说,拥有所有正确信息至关重要:加密算法、加密模式、填充模式,如果加密模式需要,IV。题外话:毛伊里克斯特拉尔?
猜你喜欢
  • 2019-10-24
  • 1970-01-01
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2018-09-30
  • 2012-06-21
  • 2013-05-10
相关资源
最近更新 更多