Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error RijndaelManaged, "Padding is invalid and cannot be removed"

I have error from CryptoStream:

Padding is invalid and cannot be removed.

Code

public MemoryStream EncrypteBytes(Stream inputStream, string passPhrase, string saltValue)
{
    RijndaelManaged RijndaelCipher = new RijndaelManaged();
    RijndaelCipher.Padding = PaddingMode.PKCS7;
    RijndaelCipher.Mode = CipherMode.CBC;
    byte[] salt = Encoding.ASCII.GetBytes(saltValue);
    PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);

    ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(password.GetBytes(32), password.GetBytes(16));
    MemoryStream memoryStream = new MemoryStream();
    CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
    var buffer = new byte[1024];
    var read = inputStream.Read(buffer, 0, buffer.Length);
    while (read > 0)
    {
        cryptoStream.Write(buffer, 0, read);
        read = inputStream.Read(buffer, 0, buffer.Length);
    }

    cryptoStream.FlushFinalBlock();
    memoryStream.Position = 0;
    return memoryStream;
}

// Example usage: DecryptBytes(encryptedBytes, "SensitivePhrase", "SodiumChloride");
public byte[] DecrypteBytes(MemoryStream memoryStream, string passPhrase, string saltValue)
{
    RijndaelManaged RijndaelCipher = new RijndaelManaged();
    RijndaelCipher.Padding = PaddingMode.PKCS7;

    RijndaelCipher.Mode = CipherMode.CBC;
    byte[] salt = Encoding.ASCII.GetBytes(saltValue);
    PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, salt, "SHA1", 2);

    ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(password.GetBytes(32), password.GetBytes(16));


    CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
    byte[] plainBytes = new byte[memoryStream.Length];

    int DecryptedCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length);

    return plainBytes;
}
like image 628
no camer Avatar asked May 01 '14 10:05

no camer


3 Answers

Use PaddingMode.Zeros to fix problem , Following code:

   public byte[] EncryptFile(Stream input, string password, string salt)
            {

                // Essentially, if you want to use RijndaelManaged as AES you need to make sure that:
                // 1.The block size is set to 128 bits
                // 2.You are not using CFB mode, or if you are the feedback size is also 128 bits

                var algorithm = new RijndaelManaged { KeySize = 256, BlockSize = 128 };
                var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(salt));

                algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
                algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);
                algorithm.Padding = PaddingMode.Zeros;

                using (Stream cryptoStream = new MemoryStream())
                using (var encryptedStream = new CryptoStream(cryptoStream, algorithm.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    CopyStream(input, encryptedStream);

                    return ReadToEnd(cryptoStream);
                }
            }

            public byte[] DecryptFile(Stream input, Stream output, string password, string salt)
            {
                // Essentially, if you want to use RijndaelManaged as AES you need to make sure that:
                // 1.The block size is set to 128 bits
                // 2.You are not using CFB mode, or if you are the feedback size is also 128 bits
                var algorithm = new RijndaelManaged { KeySize = 256, BlockSize = 128 };
                var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(salt));

                algorithm.Key = key.GetBytes(algorithm.KeySize / 8);
                algorithm.IV = key.GetBytes(algorithm.BlockSize / 8);
                algorithm.Padding = PaddingMode.Zeros;

                try
                {
                    using (var decryptedStream = new CryptoStream(output, algorithm.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        CopyStream(input, decryptedStream);
                        return ReadToEnd(output);
                    }
                }
                catch (CryptographicException ex)
                {
                    throw new InvalidDataException("Please supply a correct password");
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }

I hop help you.

like image 177
Amir Movahedi Avatar answered Nov 19 '22 01:11

Amir Movahedi


Please check your pass phrase - it should be same in both methods EncrypteBytes and DecrypteBytes. If both are not same, then it will generate the error.

like image 11
Dhaval Patel Avatar answered Nov 18 '22 23:11

Dhaval Patel


My problem was I was taking the encryped output in bytes and converting it to a string. The string back to byte array (for decrypting) was not the same. I was using UTF8Encoding, then I tried ASCIIEnconding. Neither worked.

Convert.FromBase64String/ToBase64String worked fine, got rid of the padding issues and actually decrypted the data.

like image 1
Tod Avatar answered Nov 18 '22 23:11

Tod