4

Rijndael でパスワードを解読するコードがあります

public static string DecryptPassword(string encrypted) {
    using (MemoryStream ms = new MemoryStream())
    using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
    using (ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor(mGlobalKey, mGlobalVector))
    using (CryptoStream cs = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Read)) {
        byte[] encryptedBytes = Convert.FromBase64String(encrypted);
        cs.Write(encryptedBytes, 0, encryptedBytes.Length);
        cs.FlushFinalBlock();
        return Encoding.Unicode.GetString(ms.GetBuffer(), 0, (int)ms.Length);
    }
}

問題は、暗号ストリームを破棄すると例外が発生することです

System.IndexOutOfRangeException : Index was outside the bounds of the array.
at System.Security.Cryptography.RijndaelManagedTransform.DecryptData(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolean fLast)  
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)  
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()  
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)  
at System.IO.Stream.Close()  
at System.IO.Stream.Dispose()  

同様の問題へのリンクがいくつか見つかりましたが、解決策はありません。

暗号ストリームの破棄を削除するだけで安全ですか、それとも後でファイナライザーが爆発する原因になりますか?

4

2 に答える 2

4

CryptoStreamMode.ReadモードでSteamを作成し、それに書き込もうとしています。

于 2011-06-20T22:03:01.000 に答える
1

良い解決策は見つかりませんでしたが、次の 2 つの回避策を見つけました。 A. Encrypt/Decrypt 関数を static (C#) / shared (VB) にしないでください。(RijndaelSimple オブジェクトをインスタンス化するようにコードを変更してから、Encrypt/Decrypt 関数を呼び出す必要があります。考えられる原因: 確かではありませんが、CryptoStream がスレッドセーフな方法でメモリ ストリームを使用していない可能性があります B.例外はcipherText が空の文字列の場合にのみスローされます. 1.1 では、cipherText が空の文字列の場合、この関数は空の文字列を返すために使用されていました. したがって、次のコードを Decrypt 関数の最初の行として追加するだけです: if (string.IsNullOrEmpty(cipherText))戻る "";

オプション B を // (cipherText="" の場合にのみ失敗するため、効率的なソリューションになります。// (静的関数のままで効率的であり、cipherText=" ")

于 2012-04-18T14:29:11.857 に答える