使用AES解密大文件
Decryption of large file with AES
我正在尝试解密 500 MB 的数据,但我在较大的文件上遇到内存不足异常,因此解密适用于较小的文件,无论如何我可以确保我没有得到这个内存不足异常?
key.file 的第一部分是 IV,key.file 的第二部分是密钥。
我的机器有 32 GB 的内存,所以这不是本地问题。
代码在这一行中断:var so = decrTransform.TransformFinalBlock(file, 0, file.Length);
私人无效解密数据()
{
X509Certificate2 cert;
var storeLocation = (StoreLocation)Enum.Parse(typeof(StoreLocation), "LocalMachine", true);
var storeName = (StoreName)Enum.Parse(typeof(StoreName), "My", true);
var findType = (X509FindType)Enum.Parse(typeof(X509FindType), "FindByThumbprint", true);
string thumbprint = Thumb;
try
{
X509Store certStore = new X509Store(storeName, storeLocation);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection = certStore.Certificates.Find(findType,
thumbprint, false);
certStore.Close();
cert = new X509Certificate2(certCollection[0]);
}
catch (Exception ex)
{
throw ex;
}
RijndaelManaged alg = new RijndaelManaged();
try
{
var asd = ((RSACryptoServiceProvider)cert.PrivateKey).Decrypt("file.key.path"), true);
var iv = new byte[16];
Buffer.BlockCopy(asd, 0, iv, 0, 16);
var key = new byte[32];
Buffer.BlockCopy(asd, 16, key, 0, 32);
alg.Padding = PaddingMode.PKCS7;
alg.Mode = CipherMode.CBC;
using (ICryptoTransform decrTransform = alg.CreateDecryptor(key, iv))
{
byte[] file = ReadFile(@"encrypted.file.path");
var so = decrTransform.TransformFinalBlock(file, 0, file.Length);
File.WriteAllBytes(@"SavedData.path", so);
decrTransform.Dispose();
}
}
catch (Exception ex)
{
throw ex;
}
}
尝试使用流,尤其是 CryptoStream
。 Microsoft example at the bottom of this page 实际上使用 RijndaelManaged
执行基于文件的加密,所以你很幸运。当然,您首先需要从文件流中提取 IV,例如通过逐字节读取 exactly 16 字节。仅在读取 IV 后包装流。
这样除了缓冲区大小之外不需要内存消耗,缓冲区大小应该在几 KiB 范围内。
我正在尝试解密 500 MB 的数据,但我在较大的文件上遇到内存不足异常,因此解密适用于较小的文件,无论如何我可以确保我没有得到这个内存不足异常?
key.file 的第一部分是 IV,key.file 的第二部分是密钥。
我的机器有 32 GB 的内存,所以这不是本地问题。
代码在这一行中断:var so = decrTransform.TransformFinalBlock(file, 0, file.Length);
私人无效解密数据() {
X509Certificate2 cert;
var storeLocation = (StoreLocation)Enum.Parse(typeof(StoreLocation), "LocalMachine", true);
var storeName = (StoreName)Enum.Parse(typeof(StoreName), "My", true);
var findType = (X509FindType)Enum.Parse(typeof(X509FindType), "FindByThumbprint", true);
string thumbprint = Thumb;
try
{
X509Store certStore = new X509Store(storeName, storeLocation);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection = certStore.Certificates.Find(findType,
thumbprint, false);
certStore.Close();
cert = new X509Certificate2(certCollection[0]);
}
catch (Exception ex)
{
throw ex;
}
RijndaelManaged alg = new RijndaelManaged();
try
{
var asd = ((RSACryptoServiceProvider)cert.PrivateKey).Decrypt("file.key.path"), true);
var iv = new byte[16];
Buffer.BlockCopy(asd, 0, iv, 0, 16);
var key = new byte[32];
Buffer.BlockCopy(asd, 16, key, 0, 32);
alg.Padding = PaddingMode.PKCS7;
alg.Mode = CipherMode.CBC;
using (ICryptoTransform decrTransform = alg.CreateDecryptor(key, iv))
{
byte[] file = ReadFile(@"encrypted.file.path");
var so = decrTransform.TransformFinalBlock(file, 0, file.Length);
File.WriteAllBytes(@"SavedData.path", so);
decrTransform.Dispose();
}
}
catch (Exception ex)
{
throw ex;
}
}
尝试使用流,尤其是 CryptoStream
。 Microsoft example at the bottom of this page 实际上使用 RijndaelManaged
执行基于文件的加密,所以你很幸运。当然,您首先需要从文件流中提取 IV,例如通过逐字节读取 exactly 16 字节。仅在读取 IV 后包装流。
这样除了缓冲区大小之外不需要内存消耗,缓冲区大小应该在几 KiB 范围内。