【发布时间】:2011-07-02 02:29:30
【问题描述】:
我对 C# 很陌生,所以请耐心等待。我知道这个问题被问了很多次,但我找不到我的问题的答案。
我正在保存一些数据,在将其写入文件之前,我将其转换为二进制并将其存储在数组中,然后加密然后写入文件。我以块(32 个字节)加密数据。以同样的方式,我以 32 个字节的块读取数据,然后解密该数据,然后这应该重复直到文件末尾。但是在解密时会抛出以下错误:
填充无效,无法移除。
我使用相同的密钥和 iv(硬编码,直到我让它工作)
这是我的加密代码,没有问题:
//result
byte[] data = new byte[32];
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9,50};
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);
FileStream fStream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);
//prepare data to write (byte array 'data') ...
//encrypt
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length);
data = m.ToArray();
fStream.Write(data, 0, data.Length);
这是我的解密代码:
FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);
//setup encryption (AES)
SymmetricAlgorithm aes = Aes.Create();
byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);
//result
byte[] data = new byte[32];
//loop for reading the whole file ...
int len = fStream.Read(data, 0, 32);
//decrypt
MemoryStream m = new MemoryStream();
using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
c.Write(data, 0, data.Length); //The exception is thrown in this line
data = m.ToArray();
//using the decrypted data and then looping back to reading and decrypting...
我尝试了所有我能想到的(这并不多,因为我对密码学很陌生),我到处搜索,但找不到解决问题的方法。我还帮助自己阅读C# in a Nutshell一书。
如果有人知道为什么会发生这种情况,我将非常感激,因为我没有任何想法。
感谢您的时间和回答。
编辑: 看来加密数据的大小是 48 字节(比原来多 12 字节)。为什么呢?我认为如果它们不是块大小的倍数(16 字节,我的数据是 32 字节),它只会添加字节。数据是否总是更大,并且不断增加(我需要知道这一点才能正确读取和解密)。
注意:我不能直接使用其他流,因为我需要控制输出格式,我相信在内存中加密也更安全、更快。
【问题讨论】:
-
我想Ben就在这里,你能检查一下文件以查看加密数据的输出(即二进制文件是否大于32字节?)。您需要读取整个文件并对其进行解密。
-
other @Ben:48 字节比您的输入多 16 字节,而不是 12。是什么阻止您仅使用加密流的长度?将长度保存到加密数据嵌入的任何结构/包装信封/pdu 中应该只需要几个额外的字节。
-
@SwDevMan81 我在加密后和写入文件之前检查了数组,它有 48 个字节大,是的,还有 16 个而不是 12 个 =)。我不能,因为有时文件会变得非常大,我只需要来自我将计算的位置的一个特殊数据块,因此我必须能够以类似块的方式解密文件。 @Ben Voigt 很好,如果它总是(对于相同的块大小)创建相同的大小“增量”,那么我可以适应,但我发现这些东西加起来很快就会浪费空间。
-
有道理。我想在这种情况下我会关闭填充,否则你将永远不知道从哪里读取。