8

リモート システムから送信された、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);

これは、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() が不良データエラーなしで機能するようになりました。CipherMode を修正すると、データが適切に暗号化解除されました。

話の教訓: CipherMode.ECB モードでは、少なくとも初期化ベクトルでは、初期化ベクトルを提供する必要はありません。IV が提供されない場合、プロバイダは IV を自動生成しますが、復号化は引き続き機能します (少なくとも ECB では)。

最後に、データを暗号化したプロバイダーからのすべての情報を確実に入手することが重要です。

4

1 に答える 1

9

各ポイントに答えようとしています:

  • CBC モードでは、初期化ベクトルが必要です。(キーとは異なり) シークレットである必要はないため、リモート システムから送信する必要があります。
  • IV が必要なため、null を渡すのは適切ではありません。
  • パディング モード。どのパディング モードが使用されているかを知る必要があります。
  • パディング モードが間違っているため、TransformFinalBlock はおそらく失敗します。

編集

ECB (Electronic Code Book) と CBC (Cipher Block Chaining) の違いを以下に示します。

ECB モード

CBC モード

ご覧のとおり、ECB モードでは IV は使用されません。そのため、指定しても無視されます。

于 2012-09-20T23:27:58.477 に答える