I get a run-time error Padding is invalid and cannot be removed
while trying to decrypt some data. I have read all the similar threads I found on stackoverflow and considered the following issues:
Given a different key for decryption than the one used for encryption might bring the above issue. However, as you can see in the source for testing purposes I hard-coded the keys and I still get a runtime error.
The application may be trying to use a different padding mode for decryption than the one used for encryption. Setting the mode explicitly during the encryption or decryption process didn't solve the problem.
Some say that you would need to use the
FlushFinalBlock
method so you can tell the application to put the final bits into theblocksize
. Tried putting it below the Write method, didn't work either.
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
csEncrypt.FlushFinalBlock();
}
Below are the snippets of my code:
// Encrypt
private byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
Key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
IV = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
// Check arguments.
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
byte[] encrypted;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Padding = PaddingMode.PKCS7;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
// Write all data to the stream.
swEncrypt.Write(plainText);
csEncrypt.FlushFinalBlock();
}
encrypted = msEncrypt.ToArray();
MessageBox.Show("Encrypted str: " + Encoding.UTF8.GetString(encrypted).ToString());
}
}
}
// Update buffer length
this.Buflen = encrypted.Length;
MessageBox.Show("Byte count: " + (Encoding.UTF8.GetByteCount(encrypted.ToString())).ToString());
MessageBox.Show("Decrypted: " + DecryptStringFromBytes(encrypted, this.Encryption_key, this.Encryption_iv));
// Return the encrypted bytes from the memory stream.
return encrypted;
}
// Decrypt
private string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
Key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
IV = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
UTF8Encoding e = new UTF8Encoding();
MessageBox.Show("ciperText " + cipherText.Length);
//cipherText = e.GetBytes(cipherText);
//MessageBox.Show("ciperText2 Length " + cipherText.Length);
// Check arguments.
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("Key");
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an RijndaelManaged object
// with the specified key and IV.
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
rijAlg.Padding = PaddingMode.PKCS7;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
if (cipherText.Length != rijAlg.BlockSize)
{
throw new InvalidOperationException("Invalid cipherText length");
}
plaintext = srDecrypt.ReadToEnd();
csDecrypt.FlushFinalBlock();
}
}
}
}
return plaintext;
}
byte[] encoded_message = new byte[16];
encoded_message = EncryptStringToBytes("test", this.Encryption_key,this.Encryption_iv);
I'm trying to get this working since yesterday morning. None of the solutions I found so far worked in my application. I know the code may look a bit of a mess, but please never mind the parts which are not being used - once I get this working it will surely need a bit of refactoring.
As you can see, while using a hard-coded key and IV for testing purposes the run-time error still occurs so passing different credentials for decryption than the ones used for encryption is not the cause.
Can anyone come up with an idea on how to resolve this? Thanks.