Pat*_*ick 12 c# cryptography rijndaelmanaged
我正在尝试使用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语句结束时抛出异常.
我尝试在网上搜索,但只找到了在加密和解密单个字符串时使用编码时出现的问题的答案.我使用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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我用来设置密码的方法.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);
}
Run Code Online (Sandbox Code Playgroud)
任何人都知道我可能做错了什么?
它看起来像你没有正确发送最后一块.您至少需要FlushFinalBlock()发送CryptoStream以确保发送最终块(接收流正在寻找).
顺便说一句,CipherMode.ECB就你正在做的事情而言,在安全性方面很可能是史诗般的失败.至少使用CipherMode.CBC(密码块链接)实际使用IV并使每个块依赖于前一个.
编辑:哎呀,加密流处于读取模式.在这种情况下,您需要确保读取EOF,以便CryptoStream可以处理最终块,而不是停止readBytes.如果在写入模式下运行加密流,则可能更容易控制.
还有一点需要注意:你不能假设字节数等于字节数.分组密码具有它们处理的固定块大小,除非您使用将分组密码转换为流密码的密码模式,否则将存在使密文长于明文的填充.
| 归档时间: |
|
| 查看次数: |
32060 次 |
| 最近记录: |