gpt4 book ai didi

c# - 要解密的数据长度无效

转载 作者:可可西里 更新时间:2023-11-01 08:27:14 24 4
gpt4 key购买 nike

我正在尝试使用 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)

The exception is thrown at the end of the using statement in receiveFile, when the whole file has been transferred.

I tried searching the web but only found answers to problems that arise when using Encoding when encrypting and decrypting a single string. I use a FileStream, so I don't specify any Encoding to be used, so that should not be the problem. These are my methods:

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

有人知道我可能做错了什么吗?

最佳答案

在我看来你没有正确发送最后一个 block 。您至少需要 FlushFinalBlock() 发送 CryptoStream 以确保发送最终 block (接收流正在寻找的 block )。

顺便说一下,CipherMode.ECB is more than likely an epic fail就你正在做的事情的安全性而言。至少使用 CipherMode.CBC(密码 block 链接),它实际上使用 IV 并使每个 block 都依赖于前一个 block 。

编辑:糟糕,加密流处于读取模式。在这种情况下,您需要确保读取到 EOF,以便 CryptoStream 可以处理最后一个 block ,而不是在 readBytes 之后停止。如果以写入模式运行加密流,可能更容易控制。

请注意:您不能假设输入的字节数等于输出的字节数。 block 密码具有它们处理的固定 block 大小,除非您使用将 block 密码转换为流密码的密码模式,否则将会有填充使密文比明文更长。

关于c# - 要解密的数据长度无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/942139/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com