Недопустимая длина для массива символов Base-64



как говорится в названии, я получаю:




недопустимая длина для основания-64 символа
матрица.




Я читал об этой проблеме здесь, и кажется, что
предложение состоит в том, чтобы сохранить ViewState в SQL, если он большой. Я
использование мастера с большим количеством сбора данных, так что шансы
есть ли у меня видовое состояние большое. Но, прежде чем я перейду к " store-in-DB"
решение, может быть, кто-нибудь может взглянуть и сказать мне, если у меня есть
другие варианты?



I построить письмо для доставки, используя следующий метод:



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);
}


метод шифрования выглядит так:



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);
}


вот как выглядит HTML в hotmail:




Пожалуйста, нажмите на ссылку ниже или
вставьте его в браузер для проверки
почтовый ящик.



http://localhost:1563/Accounts/VerifyEmail.aspx?a=YOHY57xYRENEOu3H+FGq1Rf09AZAI56EPjfwuK8XWKg=




на приемном конце, верифицированная Почта.aspx.на странице cs есть строка:



 string username = Cryptography.Decrypt(_webContext.UserNameToVerify, "verify");


вот геттер для UserNameToVerify:



public string UserNameToVerify
{
get
{
return GetQueryStringValue("a").ToString();
}
}


и вот метод GetQueryStringValue:



private static string GetQueryStringValue(string key)
{
return HttpContext.Current.Request.QueryString.Get(key);
}


и метод расшифровки выглядит так:



public static string Decrypt(string cipherText, string password)
{

**// THE ERROR IS THROWN HERE!!**
byte[] cipherBytes = Convert.FromBase64String(cipherText);


можно ли исправить эту ошибку с помощью исправления кода или я должен хранить ViewState в базе данных?

1228   4  

4 ответов:

длина строки в кодировке base64 всегда кратна 4. Если это не кратно 4, то = символы добавляются до тех пор, пока это не будет. Строка запроса формы ?name=value проблемы, когда value содержит = charaters (некоторые из них будут отброшены, я не помню точное поведение). Вы можете быть в состоянии уйти с добавлением правильного числа = символы перед выполнением декодирования base64.

изменить 1

вы можете найти это значение UserNameToVerify имеет "+"изменился на " "так что вам может понадобиться сделать что-то вроде этого:

a = a.Replace(" ", "+");

это должно получить правильную длину;

int mod4 = a.Length % 4;
if (mod4 > 0 )
{
    a += new string('=', 4 - mod4);
}

конечно, назвав UrlEncode (как в ответе LukeH) должно сделать все это спорным.

Я думаю, что вам просто нужно URL-encode ваша строка Base64, когда вы включаете ее в строку запроса.

кодировка base64 использует некоторые символы, которые должны быть закодированы, если они являются частью строки запроса (а именно + и /, а может = тоже). Если строка не правильно закодирована, то вы не сможете успешно декодировать ее на другом конце, следовательно, ошибки.

можно использовать HttpUtility.UrlEncode способ кодирования строку в base64:

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="
             + HttpUtility.UrlEncode(userName.Encrypt("verify")) + "\">"
             + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a="
             + HttpUtility.UrlEncode(userName.Encrypt("verify")) + "</a>";

Я еще не достаточно авторитетен, чтобы выдвигать или комментировать, но ответ LukeH был для меня на месте.

поскольку шифрование AES является стандартом для использования сейчас, он создает строку base64 (по крайней мере, все реализации шифрования/дешифрования, которые я видел). Эта строка имеет длину, кратную 4 (строка.длина % 4 = 0)

строки, которые я получал, содержали + и = в начале или конце, и когда вы просто объедините это в строку запроса URL, она будет выглядеть правильно (для например, в электронном письме, которое вы создаете), но когда ссылка следует, и страница .NET получает ее и помещает ее в это.Страница.Запрос.QueryString, эти специальные символы исчезнут, и ваша длина строки не будет кратна 4.

Как специальные символы в передней части строки (например: +), а также = в конце, вы не можете просто добавить некоторые = чтобы компенсировать разницу, как вы изменяете текст шифра таким образом, что не соответствует тому, что было на самом деле в строке исходная строка запроса.

Итак, обертывание текста шифра с помощью HttpUtility.URLEncode (не HtmlEncode) преобразует не буквенно-цифровые символы таким образом, что .NET анализирует их обратно в исходное состояние, когда он intepreted в коллекцию querystring.

хорошо, что нам нужно только сделать URLEncode при создании строки запроса для URL. На входящей стороне, он автоматически переводится обратно в исходную строку значение.

вот пример кода

string cryptostring = MyAESEncrypt(MySecretString);
string URL = WebFunctions.ToAbsoluteUrl("~/ResetPassword.aspx?RPC=" + HttpUtility.UrlEncode(cryptostring));

мое первоначальное предположение, не зная данных будет то, что UserNameToVerify не кратно 4 в длину. Проверьте FromBase64String на msdn.

// Ok
byte[] b1 = Convert.FromBase64String("CoolDude");
// Exception
byte[] b2 = Convert.FromBase64String("MyMan");

Comments

    Ничего не найдено.