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

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

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

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

Я создаю письмо для доставки, используя метод ниже:

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 в базе данных?

Длина строки с кодировкой 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"); 
  • Как использовать DataAnnotations ErrorMessageResourceName с пользовательским решением для ресурсов
  • C ++ 11 реализация и модель памяти
  • Действительно ли встроенные виртуальные функции не имеют смысла?
  • Преобразование CString в const char *
  • Почему и как избежать утечек памяти обработчика событий?
  • Массив размера массива, который отклоняет указатели
  • Может ли код, который действителен как в C, так и в C ++, создает другое поведение при компиляции на каждом языке?
  • Проверка размера объекта в Objective-C
  • Невозможно преобразовать параметр из 'const char ' в 'LPCWSTR'
  • События мыши WPF WebBrowser не работают должным образом
  • Как напечатать строку с нулевым завершением с помощью printf?
  • Давайте будем гением компьютера.