3

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

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

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

最初の Rijndael インスタンスを作成するためにこれを持っています。

    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;
    }

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

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);
    }

それで、これをしてください

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

私は cyper1 == cypher2 と cypher11 != cypher21 も rm1.GetHashCode() != rm2.GetHashCode() を取得していますが、すべてのパブリックパラメーターは同じです!

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

4

1 に答える 1

0

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

またGetHashCode()、一意性を実際に保証することはありません。実際の同等性をテストする前に、軽量の事前チェックとして使用することを意図しています。
これは、Dictionary などのあらゆる種類のハッシュ データ構造で頻繁に使用されます。

このトピックの詳細については、http:
//msdn.microsoft.com/en-us/library/system.object.gethashcode.aspxを参照してください。

私もあなたのコードを実行しましたが、私の場合は次のようになりました。

cyper1 == cypher2 and cypher11 == cypher21

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

于 2012-03-16T17:03:25.017 に答える