MVC AES (RijndaelManaged) Encryption - Padding is invalid and cannot be removed"

Greetings,

Encrypting and displaying a string of the results works fine, but the decryption in the attached code gives me the "Padding is invalid and cannot be removed" CryptographyException. I have done tons of searching on the web, and per many posts' suggestions I have added a machineKey to the global web.config file, and have set .Padding mode to ANSIX923, PKCS7, ISO10126 and None, and I get  the error every time.

If it matters, I am creating the Key in the Global.asax.cs file like so (called from Application_Start():

public static void GenerateAESKey()
        {
            AESSTuff.AES = new RijndaelManaged();
            AESSTuff.AES.Padding = PaddingMode.None;
            AESSTuff.AES.Mode = CipherMode.CBC;
            AESSTuff.AES.KeySize = 256;
            AESSTuff.AES.GenerateKey();
            AESSTuff.AES.GenerateIV();
        }
    }

    public static class AESSTuff
    {
        public static RijndaelManaged AES { get; set; }
    }

Open in new window


Now the code that is giving me the error:

using System;
using System.IO;
using System.Security.Cryptography;

namespace AESEncryption.Services
{
    public class CryptoService
    {

        public string EncryptData(string myData)
        {
            byte[] t = EncryptStringToBytesAES(myData, AESSTuff.AES.Key, AESSTuff.AES.IV);
            return Convert.ToBase64String(t);
        }

        public string DecryptData(string myData)
        {
            byte[] t = Convert.FromBase64String(myData);
            return DecryptStringFromBytesAES(t, AESSTuff.AES.Key, AESSTuff.AES.IV);
        }

        private static byte[] EncryptStringToBytesAES(string dataToEncrypt, byte[] key, byte[] IV)
        {
            MemoryStream msEncrypt = null;

            RijndaelManaged aesAlgorithm = null;

            aesAlgorithm = new RijndaelManaged();
            aesAlgorithm.Key = key;
            aesAlgorithm.IV = IV;

            ICryptoTransform encryptor = aesAlgorithm.CreateEncryptor(aesAlgorithm.Key, aesAlgorithm.IV);

            msEncrypt = new MemoryStream();
            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(dataToEncrypt);
                    swEncrypt.Flush();
                    return msEncrypt.ToArray();
                }
            }
        }

        private static string DecryptStringFromBytesAES(byte[] cipherText, byte[] key, byte[] IV)
        {
            RijndaelManaged aesAlgorithm = null;
            aesAlgorithm = new RijndaelManaged();
            aesAlgorithm.Key = key;
            aesAlgorithm.IV = IV;

            ICryptoTransform decyptor = aesAlgorithm.CreateDecryptor(aesAlgorithm.Key, aesAlgorithm.IV);

            using (MemoryStream msDecrypt = new MemoryStream(cipherText))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decyptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        return srDecrypt.ReadToEnd();
                    }
                }
            }
        }
    }
}

Open in new window


There is nothing proprietary about this code, meaning I can attach the entire project if that helps anyone in helping me.

I have been at this for two days now, and am no closer to a solution.

Any ideas?
David_GravesAsked:
Who is Participating?
 
David_GravesConnect With a Mentor Author Commented:
And... I figured it out.

I added a .Close() for the StreamWriter just before I returned my data in the encryption routine.

                    swEncrypt.Write(dataToEncrypt);
                    swEncrypt.Flush();
                    swEncrypt.Close();
                    return msEncrypt.ToArray();

Open in new window


I discovered it from the first answer in this thread. Shawn Farka mentions something about ensuring the stream gets closed at the right time so that the padding is written properly.
0
 
David_GravesAuthor Commented:
Also, I typoed the 3rd tag in the list of tags for this post and have no idea how to remove it.
0
 
David_GravesAuthor Commented:
If it matters, the string to be encrypted is simply being entered on a form, and the encryption method above is being called via AJAX. The decryption method is being called via the encryption method's AJAX success: statement.

   function Submit() {
        var dataToEncrypt = $('#DataToEncrypt').attr('value');
        alert("Submitted: " + dataToEncrypt);
        EncryptData(dataToEncrypt);
        return false;
    };
    function EncryptData(dataToEncrypt) {
        alert("EncryptData: " + dataToEncrypt);
        $.ajax(
            {
                type: 'POST',
                url: '@Url.Action("EncryptData", "Crypto")',
                dataType: 'html',
                data: { data: dataToEncrypt },
                success: function (data) { $('#encryptedString').html(data); DecryptData(data); },
                error: function (req, status, error) {
                    alert(error);
                }
            });
    };
    function DecryptData(dataToDecrypt) {
        alert("DataToDecrypt:" + dataToDecrypt);
        $.ajax(
        {
            type: 'POST',
            url: '@Url.Action("DecryptData", "Crypto")',
            dataType: 'html',
            data: { data: dataToDecrypt },
            success: function (data) { $('#decryptedString').html(data); }
        });
    };

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.