I'm getting the infamous "Padding is invalid and cannot be removed." error. However, despite ensuring the padding mode is set as well as verifying the key is the same on both encrypt and decrypt. I can't get past the issue.
What am I doing wrong o' great sages of the internet?
//Targeting .Net 4.5.2
//Key is hard coded, ONLY while working through this error in a minimum repo.
byte[] testKey = Convert.FromBase64String("KN1df3fOkLmSPyOP4r+grlVFDC/JVlWuew1u/hDGvUU=");
//Called to Encrypt ("D:\\Assets\\", "Test.txt")
public void DoWork(string filePath, string fileName){
CryptographyUtil crypto = new CryptographyUtil(testKey);
crypto.EncryptFile(filePath, fileName));
}
//Called to Decrypt ("D:\\Assets\\", "Test.txt.dat")
public void UnDoWork(string filePath, string fileName){
CryptographyUtil crypto = new CryptographyUtil(testKey);
crypto.DecryptFile(filePath, fileName));
}
public class CryptographyUtil(){
RijndaelManaged rjndl;
RNGCryptoServiceProvider cRng;
public CryptographyUtil(byte[] key, int keySize = 256, int blockSize = 256) {
cRng = new RNGCryptoServiceProvider();
rjndl = new RijndaelManaged();
rjndl.Key = key;
rjndl.KeySize = keySize;
rjndl.BlockSize = blockSize;
rjndl.Mode = CipherMode.CBC;
rjndl.Padding = PaddingMode.PKCS7;
}
public void EncryptFile(string filePath, string fileName) {
string inputFilePath = Path.Combine(filePath, fileName);
if(!File.Exists(inputFilePath)) {
throw new FileLoadException("Unable to locate or open file.", inputFilePath);
}
string outputDirectory = Path.Combine(filePath, "Encrypted");
if(!Directory.Exists(outputDirectory)){
Directory.CreateDirectory(outputDirectory);
}
string outputPath = Path.Combine(outputDirectory, fileName + ".dat");
//Create a unique IV each time
byte[] iv = new byte[rjndl.BlockSize / 8]
cRng.GetBytes(iv);
byte[] ivSize = BitConverter.GetBytes(iv.Length);
ICryptoTransform encryptor = rjndl.CreateEncryptor(rjndl.Key, iv);
using(FileStream readStream = File.OpenRead(inputFilePath)) {
using(FileStream writeStream = new FileStream(outputPath, FileMode.Create)) {
using(CryptoStream encryptStream = new CryptoStream(writeStream, encryptor, CryptoStreamMode.Write)) {
//Write the following to the file before the encrypted data:
// - length of the IV
// - the IV
writeStream.Write(ivSize, 0, ivSize.Length);
writeStream.Write(iv, 0, iv.Length);
readStream.CopyTo(encryptStream);
readStream.Flush();
encryptStream.FlushFinalBlock();
encryptStream.Close();
}
writeStream.Close();
}
readStream.Close();
}
}
public void DecryptFile(string filePath, string fileName) {
string outputDirectory = Path.Combine(filePath, "Decrypted");
if(!Directory.Exists(outputDirectory)){
Directory.CreateDirectory(outputDirectory);
}
//Remove the ".dat" from the end of the file
string outputFilePath = Path.Combine(outputDirectory, fileName.Substring(0, fileName.LastIndexOf('.')));
if(File.Exists(outputFilePath)){
File.Delete(outputFilePath);
}
using(FileStream readStream = File.OpenRead(Path.Combine(filePath, fileName))) {
//Size buffer for IV Length (int = 4 bytes)
byte[] buffer = new byte[4];
readStream.Read(buffer, 0, buffer.Length);
int ivLength = BitConverter.ToUInt16(buffer, 0);
//Re-size buffer for IV
buffer = new byte[ivLength];
//Read IV to buffer and use to create decryptor
readStream.Read(buffer, 0, ivLength);
//Use IV in buffer to create decryptor
ICryptoTransform decryptor = rjndl.CreateDecryptor(rjndl.Key, buffer);
buffer = new byte[1024];
using(FileStream writeStream = new FileStream(outputFilePath, FileMode.Create)) {
using(CryptoStream decryptStream = new CryptoStream(readStream, decryptor, CryptoStreamMode.Read)) {
//FIXME: Padding Error
int readIdx = decryptStream.Read(buffer, 0, buffer.Length);
while(readIdx > 0) {
writeStream.Write(buffer, 0, readIdx);
readIdx = decryptStream.Read(buffer, 0, buffer.Length);
}
decryptStream.Flush();
decryptStream.Close();
}
writeStream.Close();
}
readStream.Close();
}
}
}
Using RijndaelManaged as I have to create encrypted packages for legacy software that uses it to decrypt.