在这种情况下,我需要安全地加密/解密n长度的文件,理想情况下使用rijndael,但绝对是256bit加密。
我以前玩过加密技术,很高兴地对字符串和字节数组进行了加密/解密。
但是,因为我不知道文件的大小(而且讨论中的文件可能非常大(~2.5GB)是非常可行的),所以我不能像以前那样将它们加载到字节数组中并按单个绑定进行加密/解密。
所以,在谷歌上读了几遍之后,我知道答案是对文件进行分块加密和解密,所以我生成了以下代码:
private static void Enc(string decryptedFileName, string encryptedFileName)
{
FileStream fsOutput = File.OpenWrite(encryptedFileName);
FileStream fsInput = File.OpenRead(decryptedFileName);
byte[] IVBytes = Encoding.ASCII.GetBytes("1234567890123456");
fsOutput.Write(BitConverter.GetBytes(fsInput.Length), 0, 8);
fsOutput.Write(IVBytes, 0, 16);
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC};
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(passwordDB.GetBytes(256 / 8), IVBytes);
CryptoStream cryptoStream = new CryptoStream(fsOutput, encryptor, CryptoStreamMode.Write);
for (long i = 0; i < fsInput.Length; i += chunkSize)
{
byte[] chunkData = new byte[chunkSize];
fsInput.Read(chunkData, 0, chunkSize);
cryptoStream.Write(chunkData, 0, chunkData.Length);
}
cryptoStream.Close();
fsInput.Close();
fsInput.Dispose();
cryptoStream.Dispose();
}
private static void Dec(string encryptedFileName, string decryptedFileName)
{
FileStream fsInput = File.OpenRead(encryptedFileName);
FileStream fsOutput = File.OpenWrite(decryptedFileName);
byte[] buffer = new byte[8];
fsInput.Read(buffer, 0, 8);
long fileLength = BitConverter.ToInt64(buffer, 0);
byte[] IVBytes = new byte[16];
fsInput.Read(IVBytes, 0, 16);
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC };
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(passwordDB.GetBytes(256 / 8), IVBytes);
CryptoStream cryptoStream = new CryptoStream(fsOutput,decryptor,CryptoStreamMode.Write);
for (long i = 0; i < fsInput.Length; i += chunkSize)
{
byte[] chunkData = new byte[chunkSize];
fsInput.Read(chunkData, 0, chunkSize);
cryptoStream.Write(chunkData, 0, chunkData.Length);
}
cryptoStream.Close();
cryptoStream.Dispose();
fsInput.Close();
fsInput.Dispose();
}
这一切“看起来”对我好,但可悲的是,看起来似乎是欺骗!
加密工作正常,但在解密过程中,“cryptostream.close()”方法引发以下异常:
System.Security.Cryptography.Cryptographic例外
was unmanaged message=“padding is
无效,无法删除。“
source=“mscorlib”堆栈跟踪:
at system.security.cryptography.rijndaelManagedTransform.decryptData(byte[]
输入缓冲区,Int32输入缓冲区,Int32
输入计数,字节[]&输出缓冲区,
Int32输出偏移,填充模式
paddingmode,布尔flast)
at system.security.cryptography.rijndaelManagedTransform.TransformFinalBlock(byte[]
输入缓冲区,Int32输入缓冲区,Int32
输入计数)
在System.Security.Cryptography.CryptoStream.FlushFinalBlock()上
at system.security.cryptography.cryptostream.dispose(布尔值
处置)
在system.io.stream.close()上
未加密的文件大小似乎与预期的文件大小不匹配(从大约8个字节到大约60个字节)。
我通过修改rijndaelManaged对象创建行以包含填充类型来“修复”异常,如下所示:
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC,Padding=PaddingMode.None };
但文件大小仍然不匹配,可以预见,新未加密的文件是胡扯!
我承认我现在不在加密/解密的舒适区,这可能是一个新手的错误-但我不能发现它!
如有任何帮助,我们将不胜感激!