我在我的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仍然总是字节[100]) 它工作,文件被加密和解密,但解密文件的大小比原始文件大,并在文本文件的末尾包含1或2多行。
答案 0 :(得分:3)
我不知道库,但这里的一个问题是你用256位= 32字节的块大小加密100字节的块。你的块应该是32个字节的倍数。文件末尾的额外字节可能只是将最后一个块舍入到32个字节。
正如Philip的回答一样,崩溃的可能原因是Write中的硬编码100。 Crypt函数将从它正在加密的最后一个块中撤回32,64或96个字节中的一个,这些都是100个。(在100字节的情况下,有可能你的数据被填充到128字节加密和所以当你只写100时,你会丢失最后一个块的最后28个字节。)
另外
答案 1 :(得分:1)
当您对fIn.Read(...)
的呼叫指定100时,您说“读取最多 100字节” - 请注意实际字节数可能不同;您应该使用返回值来确定实际读取的数量。
在对fOut.Write
的调用中,您假设cc.Crypt(bin,key,iv,true)
的输出正好是100个字节,这不是一个有效的假设。另请注意,即使您只从文件中读取1,也始终加密bin
的所有100个字节。如果你的读数低于100,那么你将加密bin中的“遗留”(可能为0,除非以前使用过)。
修正这些长度问题,你应该走在正确的轨道上。类似的东西:
while (rdlen < totlen)
{
len = fIn.Read(bin, 0, 100);
// note that we are encrypting all of "bin" here, may want to only
// encrypt "len" bytes..
byte[] encrypted = cc.Crypt(bin, key, iv, true);
fOut.Write(encrypted, 0, encrypted.Length);
rdlen = rdlen + len;
}