2

暗号化コードをテストしようとしていますが、破棄されたときに「パディングが無効であり、削除できません」という CyrptographicException を取得し続けていますdecryptdecryptストリームの最後を超えて読み込もうとすると、同様のエラーが発生しますがCryptoStream.Read、これは問題ではないことがドキュメントに示されています。

簡単な例:

const int DATA_SET_SIZES = 102399;

byte[] iv,
        key,
        startingData = new byte[DATA_SET_SIZES],
        encryptedData = new byte[((DATA_SET_SIZES - 1) / 16 + 2) * 16],
        endingData = new byte[DATA_SET_SIZES];//[((DATA_SET_SIZES - 1) / 16 + 1) * 16];
Random rand = new Random();

rand.NextBytes(startingData);       //Get test data.

using (Rijndael cryptAlg = Rijndael.Create())
{
    cryptAlg.Mode = CipherMode.CBC;
    cryptAlg.Padding = PaddingMode.ISO10126;

    iv = cryptAlg.IV;               //Use random IV during test.
    key = cryptAlg.Key;             //Use random Key during test.
    using (CryptoStream encrypt = new CryptoStream(new MemoryStream(encryptedData), cryptAlg.CreateEncryptor(key, iv), CryptoStreamMode.Write))
    {
        encrypt.Write(startingData, 0, startingData.Length);
        encrypt.FlushFinalBlock();
    }
    using (CryptoStream decrypt = new CryptoStream(new MemoryStream(encryptedData), cryptAlg.CreateDecryptor(key, iv), CryptoStreamMode.Read))
    {
        int dataRecieved = decrypt.Read(endingData, 0, endingData.Length);
    }
}

次のいずれかを実行すると、例外はなくなります。

  • cryptAlg.Padding = PaddingMode.None暗号化を実行した後、作成する前に変更しdecryptます。
  • ブロックサイズの変更const int DATA_SET_SIZES = 102400またはその他の倍数。
  • 最後のブロックからデータを読み取らないでください。

何か間違っているのでしょうか、それとも .NET 実装がストリームの終わりを正しく認識していないのでしょうか?

また、暗号化されたデータが、暗号化されたデータを保存するために必要なブロックよりも 1 ブロック長い理由を知っている人はいますか? そのブロックには何がありますか?

4

1 に答える 1

2

バッファencryptedDataが大きすぎます。入力 15 バイトを取得すると、32 ブロックのバッファーが返されます。コンストラクターに完全なバッファーを与えるためMemoryStream、ストリームの最後まで読み取ります。ブロックの復号化は決して失敗しないため、失敗するのはパディングだけです。最後のブロックにはおそらくゼロしか含まれていないため、復号化された値はパディング形式と一致するのではなくランダムです (ほとんどの場合)。

試す:new byte[(DATA_SET_SIZES / 16 +1) * 16]

于 2013-03-02T16:22:35.230 に答える