?
Solved

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

Posted on 2011-09-13
3
Medium Priority
?
1,258 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

PowerShell Core for Advanced Linux Administrators

Understand advanced principals around Powershell Core with a focus on the Linux Administrator.  This course covers how to administer numerous environments across multiple platforms including Linux, Azure, AWS, and Google Cloud from a single shell instance.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Provide an easy one stop to quickly get the relevant information on common asked question on Ransomware in Expert Exchange.
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.
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
Suggested Courses

801 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