Я просмотрел другие посты на эту тему, но, похоже, не могу понять мою ошибку с этим. Я пытаюсь потоковое шифрование файлов с AES CBC (позже я сделаю другие). Я знаю, что мне нужно заполнить CBC и настроить его. Тем не менее, я получаю ошибку все ту же ошибку.
Message:
System.Security.Cryptography.CryptographicException : Padding is invalid and cannot be removed.
Stack Trace:
UniversalCryptoDecryptor.DepadBlock(Byte[] block, Int32 offset, Int32 count)
UniversalCryptoDecryptor.UncheckedTransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
UniversalCryptoTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
CryptoStream.ReadAsyncCore(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken, Boolean useAsync)
CryptoStream.Read(Byte[] buffer, Int32 offset, Int32 count)
EncryptionFunctions.AESDecryptCBC(String encryptedFile, String plainTextFile, Byte[] key, Byte[] iv, Int32 blockSize, Int32 bufferSize) line 82
EncryptionFunctionsUnitTests.TestEncryptAndDecryptFiles() line 39
Я пробовал различные изменения, такие как различные типы заполнения, но лучшее, что я получаю, - это какой-то тип ненужных выходных данных. Кажется, что шифрование работает нормально, хотя я не могу точно сказать, что это выходные данные гаража, так как они выглядят как набор китайских иероглифов. Входной файл - это всего лишь 3 КБ текста википедии, который я использую для тестирования.
Это две функции, которые я использую для шифрования и дешифрования.
public static void AESEncryptCBC(string plainTextFile, string encryptedFile, byte[] key, byte[] iv, int bufferSize = 65536)
{
using (FileStream fileStreamOutput = new FileStream(encryptedFile, FileMode.Create)) {
using (FileStream fileStreamInput = new FileStream(plainTextFile, FileMode.Open))
{
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.KeySize = key.Length*8; // Keysize is in bits, bytes to bits conversion
aes.BlockSize = 128; // bits
aes.Mode = CipherMode.CBC;
aes.IV = iv;
aes.Padding = PaddingMode.PKCS7;
using (CryptoStream cryptoStream = new CryptoStream(fileStreamOutput, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
int read;
byte[] readBuffer = new byte[bufferSize];
while ((read = fileStreamInput.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
cryptoStream.Write(readBuffer, 0, read);
}
}
}
}
}
}
public static void AESDecryptCBC(string encryptedFile, string plainTextFile, byte[] key, byte[] iv, int bufferSize = 65536)
{
using (FileStream fileStreamOutput = new FileStream(plainTextFile, FileMode.Create))
{
using (FileStream fileStreamInput = new FileStream(encryptedFile, FileMode.Open))
{
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.KeySize = key.Length * 8; // Keysize is in bits, bytes to bits conversion
aes.BlockSize = 128; // bits
aes.Mode = CipherMode.CBC;
aes.IV = iv;
aes.Padding = PaddingMode.PKCS7;
using (CryptoStream cryptoStream = new CryptoStream(fileStreamInput, aes.CreateDecryptor(), CryptoStreamMode.Read))
{
int read;
byte[] readBuffer = new byte[bufferSize];
while ((read = cryptoStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
fileStreamOutput.Write(readBuffer, 0, read);
}
}
}
}
}
}
Мой метод модульного тестирования, который их вызывает. Не берите в голову генератор случайных чисел, позже я использую хеш-функцию для пароля, чтобы убедиться, что у меня есть ключ правильного размера.
public void TestEncryptAndDecryptFiles()
{
string outFile = "out.txt";
string outFile2 = "out2.txt";
byte[] salt = new byte[128];
RandomNumberGenerator.Fill(salt);
int numberOfBits = 256;
int blockSize = 128;
byte[] key = new byte[numberOfBits / 8];
byte[] iv = new byte[blockSize /8];
RandomNumberGenerator.Fill(key);
RandomNumberGenerator.Fill(iv);
EncryptionFunctions.AESEncryptCBC(SampleText, outFile, key, iv);
Assert.IsTrue(File.Exists(outFile));
EncryptionFunctions.AESDecryptCBC(outFile, outFile2, key, iv);
Assert.IsTrue(File.Exists(outFile2));
Assert.AreEqual(HashFunctions.Md5(SampleText), HashFunctions.Md5(outFile2));
}
}