[英]AES encryption on file over 1GB
我正在制作一个可以加密 5 个视频文件的应用程序。 问题是它只加密了 5 个文件中的 4 个(<1gb)。 在超过 1GB 的第 5 个文件上,抛出 System.OutOfMemoryException。 (我知道我之前问过它,但我按照建议做了一些更改但它仍然不起作用,我不是要发送垃圾邮件)这是我的代码:
//Encrypts single file
public void EncryptFile(string file, string password)
{
byte[] bytesToBeEncrypted = File.ReadAllBytes(file);
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
// Hash the password with SHA256
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
byte[] salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
FileStream fsCrypt = new FileStream(file + ".enc", FileMode.Create);
//Set Rijndael symmetric encryption algorithm
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = AES.LegalKeySizes[0].MaxSize;
AES.BlockSize = AES.LegalBlockSizes[0].MaxSize;
AES.Padding = PaddingMode.PKCS7;
//"What it does is repeatedly hash the user password along with the salt." High iteration counts.
var key = new Rfc2898DeriveBytes(passwordBytes, salt, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CFB;
//write salt to the beginning of the output file, so in this case can be random every time
fsCrypt.Write(salt, 0, salt.Length);
CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write);
FileStream fsIn = new FileStream(file, FileMode.Open);
//create a buffer (1mb) so only this amount will allocate in the memory and not the whole file
byte[] buffer = new byte[5048576];
int read;
try
{
while ((read = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
Application.DoEvents();
cs.Write(buffer, 0, read);
}
fsIn.Close();
fsIn.Dispose();
}
catch (System.OutOfMemoryException ex)
{
cs.Flush();
cs.Dispose();
}
finally
{
cs.Close();
fsCrypt.Close();
}
您正在方法开始时读取整个文件:
byte[] bytesToBeEncrypted = File.ReadAllBytes(file);
这会导致 OutOfMemoryException。 这是您如何执行此操作的想法:
static void EncryptFile(string file, string password)
{
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
byte[] salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = AES.LegalKeySizes[0].MaxSize;
AES.BlockSize = AES.LegalBlockSizes[0].MaxSize;
AES.Padding = PaddingMode.PKCS7;
//"What it does is repeatedly hash the user password along with the salt." High iteration counts.
using (var key = new Rfc2898DeriveBytes(passwordBytes, salt, 1000)) // automatically dispose key
{
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CFB;
}
using (FileStream fsCrypt = new FileStream(file + ".enc", FileMode.Create)) // automatically dispose fsCrypt
{
//write salt to the beginning of the output file, so in this case can be random every time
fsCrypt.Write(salt, 0, salt.Length);
}
int bytesToRead = 128 * 1024 * 1024; // 128MB
byte[] buffer = new byte[bytesToRead]; // create the array that will be used encrypted
long fileOffset = 0;
int read = 0;
bool allRead = false;
while (!allRead)
{
using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
fs.Seek(fileOffset, SeekOrigin.Begin); // continue reading from where we were...
read = fs.Read(buffer, 0, bytesToRead); // read the next chunk
}
if (read == 0)
allRead = true;
else
fileOffset += read;
using (FileStream fsCrypt = new FileStream(file + ".enc", FileMode.Open)) // automatically dispose fsCrypt
{
using (CryptoStream cs = new CryptoStream(fsCrypt, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
fsCrypt.Seek(fileOffset, SeekOrigin.End);
cs.Write(buffer, 0, read);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.