i want to encrypt and decrypt files using Symmetric Algorithms. for small file there is no issue but if our file is large for example (100 mb, 1 GB, 5 GB,...) simple codes does not work and We have to use different methods to solve this problem. i used ChatGPT to Create a Encrypt and Decrypt Methods, Encrypt Method works fine and read large file without issues and encrypt and write encryped file on disk. but when i want to decrypt file, i get Com Exception in CryptographicEngine.Decrypt line. i tested for a tiny 3 kb Text file and issue exist. so i found that if encrypting file goes wrong decryption will be failed. so what is wrong with my encrypt method? how to fix this?
public static async Task EncryptFileAsync(string inputFile, string outputFile)
{
var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
var keyMaterial = CryptographicBuffer.GenerateRandom(provider.BlockLength);
var iv = CryptographicBuffer.GenerateRandom(provider.BlockLength);
var key = provider.CreateSymmetricKey(keyMaterial);
const int bufferSize = 4096; // Choose an appropriate buffer size
var file = await StorageFile.GetFileFromPathAsync(inputFile);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
{
using (IInputStream inputStream = stream.GetInputStreamAt(0))
{
using (DataReader dataReader = new DataReader(inputStream))
{
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
{
while (stream.Position < stream.Size)
{
dataReader.InputStreamOptions = InputStreamOptions.Partial;
uint bytesRead = await dataReader.LoadAsync(bufferSize);
if (bytesRead > 0)
{
// Convert the buffer to IBuffer
IBuffer buffer = dataReader.ReadBuffer(bytesRead);
IBuffer bufferEncrypt = CryptographicEngine.Encrypt(key, buffer, iv);
var byteArray = bufferEncrypt.ToArray();
await fs.WriteAsync(byteArray, 0, byteArray.Length);
// Your processing logic with the IBuffer goes here
}
else
{
// Break the loop if no more bytes can be read
break;
}
}
}
}
}
}
// Save the key and iv for later decryption
SaveKeyAndIV(keyMaterial, iv);
}
public static async Task DecryptFileAsync(string inputFile, string outputFile)
{
// Load the key and iv used for encryption
var (keyMaterial, iv) = LoadKeyAndIV();
var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
var key = provider.CreateSymmetricKey(keyMaterial);
const int bufferSize = 4096; // Choose an appropriate buffer size
var file = await StorageFile.GetFileFromPathAsync(inputFile);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))
{
using (IInputStream inputStream = stream.GetInputStreamAt(0))
{
using (DataReader dataReader = new DataReader(inputStream))
{
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
{
while (stream.Position < stream.Size)
{
dataReader.InputStreamOptions = InputStreamOptions.Partial;
uint bytesRead = await dataReader.LoadAsync(bufferSize);
if (bytesRead > 0)
{
// Convert the buffer to IBuffer
IBuffer buffer = dataReader.ReadBuffer(bytesRead);
IBuffer bufferDecrypt = CryptographicEngine.Decrypt(key, buffer, iv);
// Convert the decrypted buffer to byte array
var decryptedBytes = bufferDecrypt.ToArray();
await fs.WriteAsync(decryptedBytes, 0, decryptedBytes.Length);
// Your processing logic with the decrypted data goes here
}
else
{
// Break the loop if no more bytes can be read
break;
}
}
}
}
}
}
}
When you put 'try catch blocks' around parts of code, you can find out more clearly where errors are coming from. This is how they work in C#.
For the encription method:
For the decryption method: