C# 逐块解密AES文件
我有一个用256比特AES加密的PDF文件。如果我将整个文件读入内存中的字节数组,我可以非常轻松地对其进行解密,并且工作正常:C# 逐块解密AES文件,c#,windows-runtime,windows-phone-8.1,cryptography,C#,Windows Runtime,Windows Phone 8.1,Cryptography,我有一个用256比特AES加密的PDF文件。如果我将整个文件读入内存中的字节数组,我可以非常轻松地对其进行解密,并且工作正常: public static async Task<StorageFile> DecryptFile(IStorageFile file, string key, string destFilename) { var buffer = await FileIO.ReadBufferAsync(file); var pwBuffer = Cry
public static async Task<StorageFile> DecryptFile(IStorageFile file, string key, string destFilename)
{
var buffer = await FileIO.ReadBufferAsync(file);
var pwBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
pwBuffer = pwBuffer.ToArray().Take(16).ToArray().AsBuffer();
var symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesEcbPkcs7);
var cryptographicKey = symProvider.CreateSymmetricKey(pwBuffer);
var res = CryptographicEngine.Decrypt(cryptographicKey, buffer, null);
var destFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(destFilename,CreationCollisionOption.ReplaceExisting);
await FileIO.WriteBufferAsync(destFile, res);
res = null;
return destFile;
}
有什么办法让WinRT代码工作吗?如评论中所述,WinRT不支持解密文件。使用
Portable.BouncyCastle
Nuget包,我成功地编写了工作正常的代码
public static async Task<StorageFile> DecryptFile(IStorageFile file, string key, string destFilename)
{
var destFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(destFilename, CreationCollisionOption.ReplaceExisting);
var pwBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
using (var inputStream = await file.OpenStreamForReadAsync())
{
using (var outputStream = await destFile.OpenStreamForWriteAsync())
{
var engine = CipherUtilities.GetCipher("AES/ECB/PKCS7Padding");
engine.Init(false, new KeyParameter(pwBuffer.ToArray().Take(16).ToArray()));
var size = inputStream.Length;
var current = inputStream.Position;
var chunkSize = 1024 * 1024L;
var lastChunk = false;
await Task.Yield();
// Initialize DataReader and DataWriter for reliable reading and writing
// to a stream. Writing directly to a stream is unreliable.
using (var reader = new BinaryReader(inputStream))
using (var writer = new BinaryWriter(outputStream))
{
while (current < size)
{
if (size - current < chunkSize)
{
chunkSize = (uint)(size - current);
lastChunk = true;
}
var chunk = new byte[chunkSize];
reader.Read(chunk, 0, (int)chunkSize);
// The last chunk must call DoFinal() as it appends additional bytes
var processedBytes = lastChunk ? engine.DoFinal(chunk) : engine.ProcessBytes(chunk);
writer.Write(processedBytes);
current = inputStream.Position;
await Task.Yield();
}
await outputStream.FlushAsync();
}
}
}
return destFile;
}
公共静态异步任务解密文件(IStorageFile文件、字符串密钥、字符串文件名)
{
var destFile=wait ApplicationData.Current.TemporaryFolder.CreateFileAsync(destFilename,CreationCollisionOption.ReplaceExisting);
var pwBuffer=cryptographicsbuffer.ConvertStringToBinary(key,BinaryStringEncoding.Utf8);
使用(var inputStream=wait file.OpenStreamForReadAsync())
{
使用(var outputStream=await destFile.OpenStreamForWriteAsync())
{
var engine=cipherputilities.GetCipher(“AES/ECB/PKCS7Padding”);
engine.Init(false,新的键参数(pwBuffer.ToArray().Take(16.ToArray()));
变量大小=inputStream.Length;
无功电流=输入流位置;
var chunkSize=1024*1024L;
var lastChunk=false;
等待任务;
//初始化DataReader和DataWriter以实现可靠的读写
//直接写入流是不可靠的。
使用(变量读取器=新二进制读取器(inputStream))
使用(var writer=newbinarywriter(outputStream))
{
while(当前<大小)
{
if(大小-当前<块大小)
{
chunkSize=(uint)(大小-当前);
lastChunk=true;
}
var chunk=新字节[chunkSize];
reader.Read(chunk,0,(int)chunkSize);
//最后一个块在附加额外字节时必须调用DoFinal()
var processedBytes=lastChunk?engine.DoFinal(chunk):engine.ProcessBytes(chunk);
writer.Write(processedBytes);
电流=输入流位置;
等待任务;
}
等待outputStream.FlushAsync();
}
}
}
返回文件;
}
看起来它不受支持。你可以试试这个:谢谢你给我指出了正确的方向
var bytes = Encoding.UTF8.GetBytes(key);
var aes256 = new AesCryptoServiceProvider
{
Mode = CipherMode.ECB,
Key = bytes.Take(16).ToArray(),
Padding = PaddingMode.PKCS7
};
aes256.GenerateIV();
var encryptor = aes256.CreateDecryptor();
using (var dest = File.Create(destFile))
{
using (CryptoStream csEncrypt = new CryptoStream(dest, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(aes256.IV, 0, aes256.IV.Length);
using (Stream source = File.OpenRead(file)
{
byte[] buffer = new byte[2048];
int bytesRead;
while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0)
{
csEncrypt.Write(buffer, 0, bytesRead);
}
}
csEncrypt.FlushFinalBlock();
}
}
public static async Task<StorageFile> DecryptFile(IStorageFile file, string key, string destFilename)
{
var destFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(destFilename, CreationCollisionOption.ReplaceExisting);
var pwBuffer = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
using (var inputStream = await file.OpenStreamForReadAsync())
{
using (var outputStream = await destFile.OpenStreamForWriteAsync())
{
var engine = CipherUtilities.GetCipher("AES/ECB/PKCS7Padding");
engine.Init(false, new KeyParameter(pwBuffer.ToArray().Take(16).ToArray()));
var size = inputStream.Length;
var current = inputStream.Position;
var chunkSize = 1024 * 1024L;
var lastChunk = false;
await Task.Yield();
// Initialize DataReader and DataWriter for reliable reading and writing
// to a stream. Writing directly to a stream is unreliable.
using (var reader = new BinaryReader(inputStream))
using (var writer = new BinaryWriter(outputStream))
{
while (current < size)
{
if (size - current < chunkSize)
{
chunkSize = (uint)(size - current);
lastChunk = true;
}
var chunk = new byte[chunkSize];
reader.Read(chunk, 0, (int)chunkSize);
// The last chunk must call DoFinal() as it appends additional bytes
var processedBytes = lastChunk ? engine.DoFinal(chunk) : engine.ProcessBytes(chunk);
writer.Write(processedBytes);
current = inputStream.Position;
await Task.Yield();
}
await outputStream.FlushAsync();
}
}
}
return destFile;
}