tl; dr加密和解密工作正常并且正确。我检查了一切。如果我没有阅读CryptoStream
的全部内容,则会出现问题。我使用RijndaelManaged
类和该应用程序是为Windows Mobile 6.CryptoStream关闭时出现“填充无效且无法删除”的冲突
此应用程序与XML的工作,它必须加密写入磁盘的一切。获取XML(在内存中)后,它将内容直接加密到文件中。后来,应用程序必须将所有这些小型XML组合成一个大型XML,但同时我们可能需要来自XML的一些信息。为了优化内存使用,我没有加载内存中的整个XML,我使用了XmlReader
,它只从CryptoStream
读取它所需的内容。但是这与崩溃“填充是无效的,不能被删除”。
例如,这完美的作品:
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。我很感激你是否知道更清洁的解决方案。
编辑: 我测试从流中读取不同数量的字节。
- 如果我从0开始读取1,2,3或1024字节,当我关闭流时它会崩溃。
- 如果我从0开始读取1025,1026,1027或2048字节,当关闭流时它不会崩溃。
- 如果我从0开始读取2049,2050,...或4096字节,当关闭流时它会崩溃 。
- 如果我从0开始读取4097个字节,当关闭流时它不会崩溃。
- 如果我从0开始读取8192个字节,当关闭流时它将崩溃 。
IV在读取前加载。
那些不在块边界上,0 - > 1023在块边界上。块边界是(对于AES)16字节的倍数。索引从0开始。 – zaph
AES是一种基于块的加密算法,它一次处理一个块。因此,只要开始点位于加密过程中使用的块边界上并且长度是块大小的倍数,就不会在开始时开始解密。对于CBC模式,先前块在加密之前与数据进行异或并且解密必须再次与解密数据异或。请参阅[[CBC模式](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Block_Chaining_.28CBC.29))。 – zaph
我不知道我是否明白你想说什么。我总是从0读取,第一个块是IV,来自'CryptoStream'。我并不想从中间开始。 根据我阅读的内容而出现崩溃。 1 - > 1024意味着这个:如果我读取1个字节(或者2,3,...直到包含1024),那么我关闭这个流,我会崩溃。如果我读取1025字节(或1026,1027,...直到2048年),则不会崩溃。 – eli