Недопустимая длина для массива символов Base-64
Как говорится в названии, я получаю:
Недопустимая длина для массива символов Base-64.
Я прочитал об этой проблеме здесь, и кажется, что предложение состоит в том, чтобы хранить ViewState в SQL, если он большой. Я использую мастер с большим количеством сбора данных, поэтому вероятность того, что мой ViewState большой. Но прежде чем я перейду к решению «store-in-DB», может быть, кто-нибудь может взглянуть и сказать, есть ли у меня другие варианты?
- Является ли уровень оптимизации -О3 опасным в g ++?
- vector push_back вызывает copy_constructor более одного раза?
- scanf () оставляет новый символ строки в буфере
- Как преобразовать имена переименований в строку в c
- исключение catch, которое выбрасывается в другой stream
Я создаю письмо для доставки, используя метод ниже:
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.
" + "" + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" + userName.Encrypt("verify") + ""; SendEmail(to, "", "", "Account created! Email verification required.", msg); }
Метод Encrypt выглядит следующим образом:
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: // локальный: 1563 / Счета / VerifyEmail.aspx а = YOHY57xYRENEOu3H + FGq1Rf09AZAI56EPjfwuK8XWKg =
На стороне приема страница VerifyEmail.aspx.cs имеет строку:
string username = Cryptography.Decrypt(_webContext.UserNameToVerify, "verify");
Здесь используется getter для 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 в базе данных?
- Func с параметром out
- Каков самый простой способ межпроцессного взаимодействия между двумя процессами C #?
- Почему std :: vector :: operator от 5 до 10 раз быстрее, чем std :: vector :: at ()?
- Управление объемным микшером
- Параллельность: Atomic и volatile в модели памяти C ++ 11
- Визуализация AST, созданного с помощью ANTLR (в среде .NET)
- Как использовать extern для обмена переменными между исходными файлами?
- Зачем использовать указатели?
Длина строки с кодировкой 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-кодировать строку Base64, когда вы включаете ее в строку запроса.
В кодировке Base64 используются некоторые символы, которые должны быть закодированы, если они являются частью запроса (а именно +
и /
, и, возможно, =
тоже). Если строка неправильно закодирована, вы не сможете успешно декодировать ее на другом конце, следовательно, ошибки.
Вы можете использовать метод HttpUtility.UrlEncode
для кодирования строки Base64:
string msg = "Please click on the link below or paste it into a browser " + "to verify your email account.
" + _configuration.RootURL + "Accounts/VerifyEmail.aspx?a=" + HttpUtility.UrlEncode(userName.Encrypt("verify")) + "";
Я недостаточно авторитет, чтобы хоть что-то выскакивать или комментировать, но ответ LukeH был для меня интересным.
Поскольку шифрование AES является стандартным для использования в настоящее время, оно создает строку base64 (по крайней мере, все реализации шифрования / расшифровки, которые я видел). Эта строка имеет длину, кратную 4 (string.length% 4 = 0)
Строки, которые я содержал + и = в начале или в конце, и когда вы просто соединяете это с запросом URL-адреса, он будет выглядеть правильно (например, в электронном письме, которое вы создаете), но когда будет следовать ссылка и Страница .NET получает это и помещает его в this.Page.Request.QueryString, эти специальные символы исчезнут, а длина строки не будет кратной 4.
Поскольку специальные символы в FRONT строки (ex: +), а также = в конце, вы не можете просто добавить some =, чтобы изменить разницу, поскольку вы изменяете текст cypher таким образом, который не работает ‘t соответствует тому, что было на самом деле в исходном запросе.
Таким образом, обтекание cypher-текстом с помощью HttpUtility.URLEncode (а не HtmlEncode) преобразует не-буквенно-цифровые символы таким образом, чтобы гарантировать, что .NET проведет их обратно в исходное состояние, когда оно будет проиндексировано в коллекцию 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");