As the title says, I am getting:
Invalid length for a Base-64 char array.
I have read about this problem on here and it seems that the suggestion is to store ViewState in SQL if it is large. I am using a wizard with a good deal of data collection so chances are my ViewState is large. But, before I turn to the "store-in-DB" solution, maybe somebody can take a look and tell me if I have other options?
I construct the email for delivery using the below method:
public void SendEmailAddressVerificationEmail(string userName, string to)
{
string msg = "Please click on the link below or paste it into a browser to verify your email account.<BR><BR>" +
"<a href=\"" + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" +
userName.Encrypt("verify") + "\">" +
_configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" +
userName.Encrypt("verify") + "</a>";
SendEmail(to, "", "", "Account created! Email verification required.", msg);
}
The Encrypt method looks like this:
public static string Encrypt(string clearText, string Password)
{
byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);
PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32), pdb.GetBytes(16));
return Convert.ToBase64String(encryptedData);
}
Here is what the HTML looks like in hotmail:
Please click on the link below or paste it into a browser to verify your email account.
http://localhost:1563/Accounts/VerifyEmail.aspx?a=YOHY57xYRENEOu3H+FGq1Rf09AZAI56EPjfwuK8XWKg=
On the receiving end, the VerifyEmail.aspx.cs page has the line:
string username = Cryptography.Decrypt(_webContext.UserNameToVerify, "verify");
Here is the getter for UserNameToVerify:
public string UserNameToVerify
{
get
{
return GetQueryStringValue("a").ToString();
}
}
And here is the GetQueryStringValue method:
private static string GetQueryStringValue(string key)
{
return HttpContext.Current.Request.QueryString.Get(key);
}
And the decrypt method looks like:
public static string Decrypt(string cipherText, string password)
{
**// THE ERROR IS THROWN HERE!!**
byte[] cipherBytes = Convert.FromBase64String(cipherText);
Can this error be remedied with a code fix or must I store ViewState in the database?
The length of a base64 encoded string is always a multiple of 4. If it is not a multiple of 4, then =
characters are appended until it is. A query string of the form ?name=value
has problems when the value
contains =
charaters (some of them will be dropped, I don't recall the exact behavior). You may be able to get away with appending the right number of =
characters before doing the base64 decode.
Edit 1
You may find that the value of UserNameToVerify
has had "+"
's changed to " "
's so you may need to do something like so:
a = a.Replace(" ", "+");
This should get the length right;
int mod4 = a.Length % 4;
if (mod4 > 0 )
{
a += new string('=', 4 - mod4);
}
Of course calling UrlEncode
(as in LukeH's answer) should make this all moot.