I am using "AesManaged" for encryption and decryption of protected data in web application. in my scenario, i am creating a token based on "Email + CurrentDate" when user login, and send it in encrypted format back to the user(Encryption is done using AESManaged
class), and when user invokes next server side method for example "Show Report", the user/client applicaiton will also send that encrypted token with the request. At server side i decrypt the token, and after peforming conditional logic based on decrypted
token, it is decided whether the given user have access to this method or not(a kind of authorization check).
It is behaving fine(as expected) for basic flow with user providing the correct encrypted string which he gets from server or it is of same lenght but user replaces characters in the encrypted string.
However, the problem arises, when user get a string of (for example) 54 character but send only 7 character to server. then following exception occurs.
I want to avoid this exception even if the user provides invalid data. so, basically string should always be decrypted, and if it is invalid token, then i can restrict access to the resource. how can I achieve this? your answer will be appreciated.
Exception Details:
Specific code block where exception occurs:
// 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))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
Exception: "Length of the data to decrypt is invalid."
Note: i am providing same key and iv for both encryption and decryption method.
Code:
public string EncryptAuthenticationTokenAes(string plainText, byte[] Key, byte[] IV)
{
byte[] encrypted;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return Convert.ToBase64String(encrypted);
}
public string DecryptPasswordAes(string encryptedString, byte[] Key, byte[] IV)
{
// becuase it is base64, if mod4>0 then it is consider as invalid token
int mod4 = encryptedString.Length % 4;
if (mod4 > 0)
{
return string.Empty;
}
byte[] cipherText = Convert.FromBase64String(encryptedString);
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.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))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
I think that you can assume if you get this error that the token has been modified. (The decryption cannot be performed because the data structures used for decryption cannot be populated correctly. Someone can correct me if I am incorrect, but I believe
that mght be due to the AES fixed block size of 128 bits).
If your app is only seing 7 chars out of 54 that the token is normally, then I would check some encoding issues. You might want to urlencode or base64 encode your token to ensure that it doesn't contian invalid characters or character sequences that will
be modified by the transport (http) layer.
Well, In my case i just compare the length of string which i recieved from client to my server side encrypted string if they are equel this error will not show up.
thanks all for their replies
Marked as answer by sahibog on Jul 01, 2012 08:19 PM
sahibog
Member
6 Points
23 Posts
How to avoid AESManaged (C#) “Length of the data to decrypt is invalid.”
May 14, 2012 06:05 AM|LINK
I am using "AesManaged" for encryption and decryption of protected data in web application. in my scenario, i am creating a token based on "Email + CurrentDate" when user login, and send it in encrypted format back to the user(Encryption is done using AESManaged class), and when user invokes next server side method for example "Show Report", the user/client applicaiton will also send that encrypted token with the request. At server side i decrypt the token, and after peforming conditional logic based on decrypted token, it is decided whether the given user have access to this method or not(a kind of authorization check).
It is behaving fine(as expected) for basic flow with user providing the correct encrypted string which he gets from server or it is of same lenght but user replaces characters in the encrypted string.
However, the problem arises, when user get a string of (for example) 54 character but send only 7 character to server. then following exception occurs.
I want to avoid this exception even if the user provides invalid data. so, basically string should always be decrypted, and if it is invalid token, then i can restrict access to the resource. how can I achieve this? your answer will be appreciated.
Exception Details:
Specific code block where exception occurs:
// 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)) { plaintext = srDecrypt.ReadToEnd(); } } }Exception: "Length of the data to decrypt is invalid."
Exception Details:
Target Site: {Byte[] TransformFinalBlock(Byte[], Int32, Int32)}
Declaring Type: {Name = "RijndaelManagedTransform" FullName = "System.Security.Cryptography.RijndaelManagedTransform"}
Name: TransformFinalBlock
Note: i am providing same key and iv for both encryption and decryption method.
Code:
public string EncryptAuthenticationTokenAes(string plainText, byte[] Key, byte[] IV) { byte[] encrypted; // Create an AesManaged object // with the specified key and IV. using (AesManaged aesAlg = new AesManaged()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decrytor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.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); } encrypted = msEncrypt.ToArray(); } } } // Return the encrypted bytes from the memory stream. return Convert.ToBase64String(encrypted); } public string DecryptPasswordAes(string encryptedString, byte[] Key, byte[] IV) { // becuase it is base64, if mod4>0 then it is consider as invalid token int mod4 = encryptedString.Length % 4; if (mod4 > 0) { return string.Empty; } byte[] cipherText = Convert.FromBase64String(encryptedString); // Declare the string used to hold // the decrypted text. string plaintext = null; // Create an AesManaged object // with the specified key and IV. using (AesManaged aesAlg = new AesManaged()) { aesAlg.Key = Key; aesAlg.IV = IV; // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.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)) { plaintext = srDecrypt.ReadToEnd(); } } } } return plaintext; }encrypt
BrockAllen
All-Star
28072 Points
4996 Posts
MVP
Re: How to avoid AESManaged (C#) “Length of the data to decrypt is invalid.”
May 14, 2012 02:02 PM|LINK
So you're tyring to see if the token was changed by the user? You typically accomplish this with a MAC.
encrypt
DevelopMentor | http://www.develop.com
thinktecture | http://www.thinktecture.com/
wikkard
Member
204 Points
38 Posts
Re: How to avoid AESManaged (C#) “Length of the data to decrypt is invalid.”
Jun 12, 2012 07:13 AM|LINK
I think that you can assume if you get this error that the token has been modified. (The decryption cannot be performed because the data structures used for decryption cannot be populated correctly. Someone can correct me if I am incorrect, but I believe that mght be due to the AES fixed block size of 128 bits).
If your app is only seing 7 chars out of 54 that the token is normally, then I would check some encoding issues. You might want to urlencode or base64 encode your token to ensure that it doesn't contian invalid characters or character sequences that will be modified by the transport (http) layer.
www.icle.com.au
www.wikkard.net
sahibog
Member
6 Points
23 Posts
Re: How to avoid AESManaged (C#) “Length of the data to decrypt is invalid.”
Jul 01, 2012 08:19 PM|LINK
Well, In my case i just compare the length of string which i recieved from client to my server side encrypted string if they are equel this error will not show up.
thanks all for their replies