我已经审查了有关此主题的其他帖子,但似乎无法弄清楚我对此的错误。我正在尝试使用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 KB维基百科文字。
这是我用于加密和解密的两个功能。
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(outFile), HashFunctions.Md5(outFile2));
}
}
[知道了,我需要更改代码以使用aes.CreateEncryptor(key,iv)
。我终于发现,调用CreateEncryptor()
或CreateEncryptor(null, null)
会自动生成一个初始化向量和一个密钥,这些密钥会覆盖我用aes.key
和aes.iv
设置的设置。我可以设置一些愚蠢的东西,然后用显然不打算这样做的函数将其覆盖。也许是一个错误,因为一页确实显示“使用当前的Key属性和初始化向量(IV)创建对称的加密对象”。它不是基于我之前的代码执行的。