我在 C# 项目中使用 OpenSSL Crypto 库来加密/解密文件。这是我的代码:
byte[] key = System.Text.Encoding.ASCII.GetBytes("password");
byte[] iv = System.Text.Encoding.ASCII.GetBytes("1234");
OpenSSL.Crypto.CipherContext cc = new OpenSSL.Crypto.CipherContext(
OpenSSL.Crypto.Cipher.AES_256_ECB);
FileStream fIn = new FileStream("C:\\file.txt", FileMode.Open,
FileAccess.Read);
FileStream fOut = new FileStream("C:\\encrypted.txt", FileMode.OpenOrCreate,
FileAccess.Write);
fOut.SetLength(0);
byte[] bin = new byte[100];
long rdlen = 0;
long totlen = fIn.Length;
int len;
DateTime start = DateTime.Now;
while (rdlen < totlen)
{
// argument 1
len = fIn.Read(bin, 0, 100);
// argument 2
fOut.Write(cc.Crypt(bin,key,iv,true),0,100);
rdlen = rdlen + len;
}
fOut.Flush();
fOut.Close();
fIn.Close();
结果我得到了这个异常:
偏移量和长度超出范围
对于数组或计数大于
从索引到的元素数量
源集合结束。
当我将参数 1 和 2 的值从 100 更改为 64 时(bin 仍然始终是 byte[100])
它工作了,文件被加密和解密,但解密文件的大小比原始文件大,并且在文本文件末尾包含 1 或 2 行以上。
我不知道这个库,但这里的一个问题是,您正在使用 256 位 = 32 字节的块大小加密 100 字节的块。您的块应该是 32 字节的倍数。文件末尾的额外字节可能只是将最终块四舍五入到 32 字节。
正如 Philip 的回答所示,崩溃的可能原因是 Write 中的硬编码 100。 Crypt 函数将从其加密的最终块中返回 32、64 或 96 字节之一,这些字节都小于 100。(在有效的 100 字节情况下,您的数据可能会被填充到加密的 128 字节,并且因此,当您只写入 100 时,就会丢失最后一个块的最后 28 个字节。)
Also
- 你正在 ECB 模式下传递 IV - 你不需要这个
- 通过重复调用 Crypt,您可能会为每 100 个字节进行密钥设置。这是低效的;您只需在加密开始时执行一次。您应该寻找一种方法来使用密钥(以及其他模式中的 IV)初始化类,然后立即向其提供数据块进行加密,而不是每次都使用密钥调用 Crypt。我不知道这个图书馆里有什么,但它应该存在。按照目前的情况,您也不能使用 CBC 或任何类似的模式,因为您将每 100 字节而不是一次写入 IV,并且不会将最后一个块链接在相邻的 100 字节块之间。
- 如果你想使用 Crypt,为什么不立即将文件加载到内存中呢?我意识到这不会扩展到千兆字节的数据,但在您的正常用例中可能是可能的。或者至少选择一个更大的数据大小,例如256k。然而,如果你超过一个街区,你仍然会面临重复的钥匙设置/损坏的 CBC。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)