2012-02-09 6 views
3

RijndaelManagedで奇妙な問題が発生しています。基本的に私はCipherMode、Padding、IV、Keyを設定した新しいインスタンスを持っています。次に、別のインスタンスを作成し、元のインスタンスの2番目のインスタンスに同じプロパティ値を割り当てます:Mode、Padding、KeySize、FeedbackSize、BlockSize、IVおよびKey。RijndaelManaged暗号化で不定な動作が発生する

したがって、すべてのプロパティ値をインスタンス1からインスタンス2にコピーしても、同じ結果が得られるはずですか?違う!両方のインスタンスのGetHashCode()は何とか違いますが、それらのプロパティ(上記の名前)をダンプすると、それらはすべて同じになります。

ブロックサイズ(16バイト、128ビット)に等しい長さのテキスト文字列を暗号化すると、同じ結果が生成されます。入力がBlockSizeより小さければ、暗号化結果は同じになりません。

これは初期のRijndaelインスタンスを作成するためのものです。 !私もそのcyper1 == cypher2とcypher11 = cypher21を取得しています。この

RijndaelManaged rm1 = CreateSymmetricKey("there is something weird happening"); 
RijndaelManaged rm2 = new RijndaelManaged(); 
// copy ALL public properties to the new instance so that it has the same parameters 
rm2.BlockSize = rm1.BlockSize; // 128 
rm2.FeedbackSize = rm1.FeedbackSize; // 128 
rm2.KeySize = rm1.KeySize; // 256 
rm2.Mode = rm1.Mode; // CBC 
rm2.Padding = rm1.Padding; // PKCS7 
rm2.IV = rm1.IV; 
rm2.Key = rm1.Key; 
// Encryption 
string cypher1 = Encrypt(rm1, "this is a test 6"); // length equal to BlockSize 
string cypher2 = Encrypt(rm2, "this is a test 6"); // length equal to BlockSize 
string cypher11 = Encrypt(rm1, "this is a test"); // length less than BlockSize 
string cypher21 = Encrypt(rm2, "this is a test"); // length less than BlockSize 

を行うそれでは

private string Encrypt(RijndaelManaged rm, string text) 
    { 
     byte[] encrypted; 
     // Create a decrytor to perform the stream transform. 
      ICryptoTransform encryptor = rm.CreateEncryptor(rm.Key, rm.IV); 
     using (MemoryStream msEncrypt = new MemoryStream()) 
      { 
       using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
       { 
        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
        { 
         //Write all data to the stream. 
         swEncrypt.Write(text); 
        } 
        encrypted = msEncrypt.ToArray(); 
       } 
      } 
     return BitConverter.ToString(encrypted); 
    } 

:例のために文字列を暗号化するために

public static RijndaelManaged CreateSymmetricKey(string passphrase) 
    { 
     RijndaelManaged symCrypto = new RijndaelManaged(); 
     symCrypto.Mode = CipherMode.CBC;    
     symCrypto.Padding = PaddingMode.PKCS7; 
     byte[] salt = Encoding.UTF8.GetBytes("dummy dummy dummy dummy test"); 
     Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(passphrase, salt); 
     symCrypto.Key = key.GetBytes(symCrypto.KeySize/8); 
     symCrypto.IV = key.GetBytes(symCrypto.BlockSize/8); 

     return symCrypto; 
    } 

rm1.GetHashCode()!= rm2.GetHashCode()しかし、すべてのパブリックパラメータは同じです!

私は両方のインスタンスのすべてのパブリックプロパティをダンプして、何かが欠落しているかどうかを確認しましたが、すべての値は同じです。

+0

http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx –

+0

この解決方法は不明ですが、配列に変換する前にストリーム上でFlushFinalBlockを呼び出す。私はそれがなければうまくいかないことを思い出しているようです。 –

+1

私は 'cyper11!= cyperh21'を再作成できません。私の前のコメントに基づいて、私はハッシュコードが一致するとは思わないでしょう。しかし、すべての必要なコードを提供するために+1 –

答えて

0

このようにGetHashCode()を使用しないでください。ベースobject.GetHashCode()の実装をオーバーライドしなかったクラスの場合、この特定のインスタンスの整数ハンドラを返します。
2つの異なるインスタンスのハンドルが常に異なるため、これは決して一致しません。

GetHashCode()実際に同等性がテストされる前に、軽量プレチェックとして使用されることを意味します。
これは大きく、このトピックに関する詳細情報についてなど

辞書のようなハッシュデータ構造の任意の種類で使用されます。
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx

私はまた、あなたのコードを実行し、私のために、以下のケースだった。

cyper1 == cypher2 and cypher11 == cypher21 

私はかなり問題がGetHashCode()の比較だったと確信しています。

関連する問題