tl; dr 加密和解密工作正常且正确。我查了一切。当我从CryptoStream
读取整个内容时,会出现问题。我使用RijndaelManaged
类,该应用程序适用于Windows Mobile 6。
此应用程序适用于XML,它必须加密写入磁盘的所有内容。获得XML(在内存中)后,它会将内容直接加密到文件中。之后,应用程序必须将所有这些小型XML组合成一个大型XML,但与此同时,我们可能需要XML中的一些信息。为了优化内存使用,我没有将整个XML加载到内存中,我使用XmlReader
只从CryptoStream
读取它所需要的内容。但这与" Padding崩溃无效,无法删除" 。
例如,这非常有效:
using (var fileStream = new FileStream(ResponsePath, FileMode.Open))
using (var crpytoStream = new CryptoStream(fileStream, key.CreateDecryptor(), CryptoStreamMode.Read))
using (var reader = StreamReader.Create(crpytoStream, settings))
{
reader.ReadToEnd();
}
而这不是:
using (var fileStream = new FileStream(ResponsePath, FileMode.Open))
using (var crpytoStream = new CryptoStream(fileStream, key.CreateDecryptor(), CryptoStreamMode.Read))
using (var reader = StreamReader.Create(crpytoStream, settings))
{
var buffer = new char[1024];
reader.ReadBlock(buffer , 0, 1024);
}
我有一个解决方案,但它看起来像一个可怕的黑客,它对巨大的XML并不好。如果您了解更清洁的解决方案,我感谢您
编辑: 我测试了从流中读取不同数量的字节。
在阅读之前加载IV。
答案 0 :(得分:0)
解决方案是创建另一个流来读到最后。在我从XML获取所需的所有数据后,我创建了一个StreamReader
并阅读了所有内容。如果XML是巨大的,这显然是不好的。
using (var workaroundStream = new StreamReader(crpytoStream))
{
var workaroundBuffer = new char[1024];
while (workaroundStream.ReadBlock(workaroundBuffer, 0, 1024) != 0)
{
}
}
答案 1 :(得分:0)
可以从加密数据的中间读取和解密。
注意:
AES是一种基于块的加密算法,它一次处理一个块。因此,只要起始点位于加密期间使用的块边界上并且长度是块大小的倍数,就可以从开头以外开始解密。
对于CBC模式,先前的块与加密前的数据相关,并且在解密时必须再次与解密的数据进行对比。请参阅CBC mode。
请参阅PKCS#7 padding。