Invalid length for a base-64 char array error

I have been working on a project that needs to encrypt and decrypt the query string of a page, and I get the “invalid length for a base-64 char array” error intermittently. Thanks to this post (the third reply by Kagisho), I got the error fixed.

But what caused this error? And why does it not happen all the time?

Here is my encryption function and decryption function:

private string EncryptString(string inString)
{
    RijndaelManaged sysAlg = new RijndaelManaged();
    byte[] salt = Encoding.ASCII.GetBytes(ConfigurationManager.AppSettings["EncryptionSalt"]);
    Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(ConfigurationManager.AppSettings["EncryptionPassword"], salt);
    sysAlg.Key = key.GetBytes(sysAlg.KeySize / 8);
    sysAlg.IV = key.GetBytes(sysAlg.BlockSize / 8);
    byte[] inBlock = UnicodeEncoding.Unicode.GetBytes(inString);
    ICryptoTransform xfrm = sysAlg.CreateEncryptor(sysAlg.Key, sysAlg.IV);
    byte[] outBlock = xfrm.TransformFinalBlock(inBlock, 0, inBlock.Length);
    return Convert.ToBase64String(outBlock);
}
private string DecryptString(string inString)
{
    RijndaelManaged sysAlg = new RijndaelManaged();
    byte[] salt = Encoding.ASCII.GetBytes(ConfigurationManager.AppSettings["EncryptionSalt"]);
    Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(ConfigurationManager.AppSettings["EncryptionPassword"], salt);
    sysAlg.Key = key.GetBytes(sysAlg.KeySize / 8);
    sysAlg.IV = key.GetBytes(sysAlg.BlockSize / 8);
    ICryptoTransform xfrm = sysAlg.CreateDecryptor(sysAlg.Key, sysAlg.IV);
    byte[] inBlock = Convert.FromBase64String(inString);
    byte[] outBlock = xfrm.TransformFinalBlock(inBlock, 0, inBlock.Length);
    return UnicodeEncoding.Unicode.GetString(outBlock);
}

It turned out that the error has nothing to do with neither the encryption function nor the decryption function. The problem was caused by the fact that if the encrypted string contains “+” sign, and is passed to another page through the query string, then the “+” sign will be converted to “ “ (space), which causes the above error when the query string is converted to a base-64 char array. So as suggested by Kagisho in the post above, I used String.Replace function to change the empty space (“ “) in the query string back to the “+” sign before decrypting it, and it worked like a charm.

string encryptedID = Request.QueryString["InvID"];
encryptedID = encryptedInvitationID.Replace(" ", "+");
string realID = this.DecryptString(encryptedID);

Sometimes you may find that after the fix you still encounter the same error, it is because the length of the encrypted string somehow is now the multiple of 4. In this case, the encrypted string needs to be padded with “=” to make the length valid before it is passed to the String.DecryptString method.

if (encryptedID.Length % 4 > 0)
{
    encryptedID = encryptedID.PadRight(encryptedID.Length + 4 - encryptedID.Length % 4, '=');
}

Hope it will help you too.

Leave a Reply

avatar
  Subscribe  
Notify of