Solved

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

Posted on 2011-09-13
3
1,215 Views
Last Modified: 2012-05-12
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?
0
Comment
Question by:David_Graves
  • 3
3 Comments
 

Author Comment

by:David_Graves
ID: 36531647
Also, I typoed the 3rd tag in the list of tags for this post and have no idea how to remove it.
0
 

Author Comment

by:David_Graves
ID: 36531721
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
 

Accepted Solution

by:
David_Graves earned 0 total points
ID: 36531888
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

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

In this era, as you know, cybercrime and other sorts of frauds using the internet has increased day by day. We should protect our information assets and confidential information from getting exploiting by the attacker or intruders. Most of the fraud…
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now