windows phone 8-C#AesManaged异常:填充无效,无法删除
本文关键字:删除 无效 填充 phone 8-C#AesManaged 异常 windows | 更新日期: 2023-09-27 17:57:33
我知道有很多这样的问题有答案,但我花了很多小时在谷歌上搜索,并尝试了我找到的所有建议。
我下载了一个文件,并希望将其加密存储在隔离存储中。这就是我存储它的方式:
using (var fs = new IsolatedStorageFileStream(fileName, FileMode.Create, store))
{
byte[] bytesInStream = new byte[args.Result.Length];
args.Result.Read(bytesInStream, 0, bytesInStream.Length);
var aes = new AesManaged
{
Key = GetBytes("aaaaaaaa"),
IV = GetBytes("bbbbbbbb")
};
byte[] encryptedArray;
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(bytesInStream, 0, bytesInStream.Length);
cryptoStream.FlushFinalBlock();
encryptedArray = memoryStream.ToArray();
}
}
fs.Write(encryptedArray, 0, encryptedArray.Length);
fs.Flush();
}
以下代码用于从隔离存储中读取文件并对其进行解密:
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (store.FileExists(fileName))
{
var file = store.OpenFile(fileName, FileMode.Open,FileAccess.Read,FileShare.Read);
var reader = new BinaryReader(file);
var aes = new AesManaged
{
Key = GetBytes("aaaaaaaa"),
IV = GetBytes("bbbbbbbb")
};
byte[] decodedContent;
byte[] encodedContent = reader.ReadBytes(1280);
using (MemoryStream ms = new MemoryStream(encodedAudio))
{
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
BinaryReader r= new BinaryReader(cs);
decodedContent= r.ReadBytes(encodedContent.Length);
}
}
}
当程序到达这一行时:decodeContent=r.ReadBytes(encodeContent.Length) 我得到CryptographicException,并显示以下消息:填充无效,无法删除
有人能帮我解决这个问题吗?
您无法按块解密,因为silverlight AesManaged总是包含填充,并且如果您只读取加密块的一部分,则解密类找不到应该删除的填充。您只能解密整个数据。或者,您可以在算法的加密部分手动拆分数据。Hans Passant也告诉过你,只是简短地说了一句;)
如果在最后一个块之前不删除填充进行解密,则一次可以解密1280个字节。也就是说,您必须将解密器设置为,而不是删除除最后一个块之外的所有块上的填充(即"无填充")。
即当有N个区块时:
- 对于块1到N-1:解密(1280字节,无填充)
- 对于块N:解密(无论剩余多少字节,填充)
您也可以在"无填充"的情况下运行整个解密过程,并自己去掉填充。最后一个字节将提供从末尾截取的字节数,从1到16。
如果你不能在解密时关闭填充删除(上面的评论暗示了这一点),你仍然可以一次解密1280个字节。只需单独加密块即可。他们每个人都会得到填充物,使其适合1280。例如,一次加密1279个字节(每个块都有一个1字节的填充。)用填充加密整个1280将得到1296个字节(16字节明文的倍数将得到一个完整的16字节填充。)
编辑,为感兴趣的:
如果你发现自己有一个大密文,并且你想分块解密,并且由于某种原因,你的解密受到限制,以至于你被迫使用填充模式PKCS#7,你仍然可以一次解密一个块的数据。它有点贵——每个块需要额外加密16字节,但至少这是可能的。
取每个原始密文块,并为每个块加密一个16字节的小尾部,该尾部为该块正确填充。然后解密放大的块,最后删除用于加密填充尾部的额外数据位。
您只需将块的最后16个字节作为IV,并使用相同的密钥加密一些小数据——例如一个字节——填充PKCS#7。将16字节的加密结果附加到块,现在解密块+16字节。填充是从尾部16字节中删除的,您可以删除数据位,最终得到原始的明文块。在我的回答中查看更多信息