私はRijndaelManagedを使用してソケット上でファイルストリームを暗号化および復号化しようとしていますが、例外にぶつかり続けます。解読するデータの長さが無効です
CryptographicException: Length of the data to decrypt is invalid. 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)
receiveFileのusingステートメントの最後に例外がスローされます。転送されました。
Webを検索しようとしましたが、1つの文字列を暗号化および復号化するときにエンコードを使用するときに発生する問題に対する答えが見つかりました。私はFileStreamを使用するので、使用するエンコーディングを指定しないので、問題ではありません。これらは私の方法です:
private void transferFile(FileInfo file, long position, long readBytes)
{
// transfer on socket stream
Stream stream = new FileStream(file.FullName, FileMode.Open);
if (position > 0)
{
stream.Seek(position, SeekOrigin.Begin);
}
// if this should be encrypted, wrap the encryptor stream
if (UseCipher)
{
stream = new CryptoStream(stream, streamEncryptor, CryptoStreamMode.Read);
}
using (stream)
{
int read;
byte[] array = new byte[8096];
while ((read = stream.Read(array, 0, array.Length)) > 0)
{
streamSocket.Send(array, 0, read, SocketFlags.None);
position += read;
}
}
}
private void receiveFile(FileInfo transferFile)
{
byte[] array = new byte[8096];
// receive file
Stream stream = new FileStream(transferFile.FullName, FileMode.Append);
if (UseCipher)
{
stream = new CryptoStream(stream, streamDecryptor, CryptoStreamMode.Write);
}
using (stream)
{
long position = new FileInfo(transferFile.Path).Length;
while (position < transferFile.Length)
{
int maxRead = Math.Min(array.Length, (int)(transferFile.Length - position));
int read = position < array.Length
? streamSocket.Receive(array, maxRead, SocketFlags.None)
: streamSocket.Receive(array, SocketFlags.None);
stream.Write(array, 0, read);
position += read;
}
}
}
これは私が暗号を設定するのに使う方法です。 byte [] initは生成されたバイト配列です。
private void setupStreamCipher(byte[] init)
{
RijndaelManaged cipher = new RijndaelManaged();
cipher.KeySize = cipher.BlockSize = 256; // bit size
cipher.Mode = CipherMode.ECB;
cipher.Padding = PaddingMode.ISO10126;
byte[] keyBytes = new byte[32];
byte[] ivBytes = new byte[32];
Array.Copy(init, keyBytes, 32);
Array.Copy(init, 32, ivBytes, 0, 32);
streamEncryptor = cipher.CreateEncryptor(keyBytes, ivBytes);
streamDecryptor = cipher.CreateDecryptor(keyBytes, ivBytes);
}
誰かが私が間違っているかもしれない考えを持っていますか?
FlushFinalBlock()メソッドは、私はCipherModeを変更します
使用して文の「クローズセクション」で呼び出されますが、私はいずれかの私の暗号を初期化しないことを知っているので、私は一例として、それを入力します"奇妙な"方法。 sendFile()のreadBytesはまだ使用されていませんが、削除するのを忘れていました。私はファイルの最後まで読んでいるので、ここでは問題にはならないはずです。 さんがパディングを担当していたと思いますか?それを機能させるために私は何を変えることができますか? – Patrick暗号化ストリームが読み取りモードの場合、最後のブロックは廃棄すると失われます。最終的なブロックを生成するためには、実際にファイルの終わりを元のソースストリームから読み取る必要があります。 –
Jeffreyへの応答:stream.FlushFinalBlock()を呼び出そうとすると、NonSupportedExceptionと表示されます。同じストリームでFlushFinalBlockを2回呼び出すことはできません。これは、ファイルの終わりが読み取られ(そして送信された)ことを意味しませんか? – Patrick