Usando el cifrado Rijndael para archivos grandes

Estoy en una situación en la que necesito cifrar / descifrar un archivo de n de longitud de forma segura, idealmente usando Rijndael, pero definitivamente con un cifrado de 256 bits.

He jugado con cifrado antes y he codificado / descifrado cadenas y matrices de bytes muy felizmente. Sin embargo, debido a que no sé el tamaño del archivo (y es muy factible que los archivos en cuestión puedan ser bastante grandes (~ 2.5 gb), no puedo simplemente cargarlos en una matriz de bytes y cifrarlos / descifrarlos en un solo salto como lo he hecho antes.

Entonces, después de leer un poco en Google, sabía que la respuesta era cifrar y descifrar el archivo en fragmentos, por lo que produje el siguiente código:

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();                      
} 

Todo se "ve" bien para mí, ¡pero por desgracia parece engañoso!

El cifrado funciona sin errores, pero durante el descifrado, el método "cryptoStream.Close ()" genera la siguiente excepción:

System.Security.Cryptography.CryptographicException no se manejó Mensaje = "El relleno no es válido y no se puede quitar".
Source = "mscorlib" StackTrace: en System.Security.Cryptography.RijndaelManagedTransform.DecryptData (Byte [] inputBuffer, Int32 inputOffset, Int32 inputCount, Byte [] & outputBuffer, Int32 outputOffset, PaddingMode paddingMode, Boolepto f. .RijndaelManagedTransform.TransformFinalBlock (Byte [] inputBuffer, Int32 inputOffset, Int32 inputCount) en System.Security.Cryptography.CryptoStream.FlushFinalBlock () en System.Security.Cryptography.CryptoStream.Dispose (System Boosean. ()

También parece que el tamaño de archivo no cifrado no coincide con el tamaño de archivo esperado (que varía de alrededor de 8 bytes a alrededor de 60)

"Solucioné" la excepción alterando las líneas de creación de objetos RijndaelManaged para incluir un tipo de relleno, como se muestra a continuación:

RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC,Padding=PaddingMode.None };

¡Pero los tamaños de archivo aún no coinciden y, como era de esperar, el archivo recién sin cifrar es falso!

Admitiré que ahora estoy fuera de mi zona de confort con cifrado / descifrado, y probablemente sea un error de novato, ¡pero no puedo detectarlo!

¡Cualquier ayuda para resolver esto sería muy apreciada!

Respuestas a la pregunta(2)

Su respuesta a la pregunta