Longueur non valide pour un tableau de caractères Base-64

Comme le titre l’indique, je reçois:

Longueur non valide pour un tableau de caractères Base-64.

J’ai lu à propos de ce problème ici et il semble que la suggestion soit de stocker ViewState en SQL s’il est volumineux. J’utilise un assistant avec beaucoup de collecte de données, donc il est probable que mon ViewState soit volumineux. Mais avant de passer à la solution “store-in-DB”, peut-être que quelqu’un peut jeter un coup d’œil et me dire si j’ai d’autres options?

Je construis l’e-mail pour la livraison en utilisant la méthode ci-dessous:

public void SendEmailAddressVerificationEmail(ssortingng userName, ssortingng to) { ssortingng 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); }

La méthode Encrypt ressemble à ceci:

 public static ssortingng Encrypt(ssortingng clearText, ssortingng 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.ToBase64Ssortingng(encryptedData); } 

Voici à quoi ressemble le HTML dans hotmail:

Veuillez cliquer sur le lien ci-dessous ou collez-le dans un navigateur pour vérifier votre compte de messagerie.

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

À la réception, la page VerifyEmail.aspx.cs comporte la ligne suivante:

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

Voici le getter pour UserNameToVerify:

 public ssortingng UserNameToVerify { get { return GetQuerySsortingngValue("a").ToSsortingng(); } } 

Et voilà la méthode GetQuerySsortingngValue:

 private static ssortingng GetQuerySsortingngValue(ssortingng key) { return HttpContext.Current.Request.QuerySsortingng.Get(key); } 

Et la méthode decrypt ressemble à:

 public static ssortingng Decrypt(ssortingng cipherText, ssortingng password) { **// THE ERROR IS THROWN HERE!!** byte[] cipherBytes = Convert.FromBase64Ssortingng(cipherText); 

Cette erreur peut-elle être résolue avec un correctif de code ou dois-je stocker ViewState dans la firebase database?

La longueur d’une chaîne codée en base64 est toujours un multiple de 4. S’il ne s’agit pas d’un multiple de 4, les caractères = sont ajoutés jusqu’à ce qu’il le soit. Une chaîne de requête de la forme ?name=value Name ?name=value a des problèmes lorsque la value contient = charaters (certains d’entre eux seront supprimés, je ne me souviens pas du comportement exact). Vous pourrez peut-être append le bon nombre de caractères avant de lancer le décodage en base64.

Modifier 1

Vous pouvez constater que la valeur de UserNameToVerify a eu "+" changé à " " de sorte que vous devrez peut-être faire quelque chose comme ça:

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

Cela devrait avoir la longueur juste;

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

Bien sûr, appeler UrlEncode (comme dans la réponse de LukeH) devrait rendre cela impossible.

Je suppose que vous devez simplement encoder votre chaîne Base64 par URL lorsque vous l’incluez dans la chaîne de requête.

L’encodage Base64 utilise des caractères qui doivent être encodés s’ils font partie d’une chaîne de requête (à savoir + et / , et peut-être aussi = ). Si la chaîne n’est pas correctement encodée, vous ne pourrez pas la décoder à l’autre bout, d’où les erreurs.

Vous pouvez utiliser la méthode HttpUtility.UrlEncode pour encoder votre chaîne Base64:

 ssortingng 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")) + "";

Je ne suis pas assez fiable pour voter ou commenter, mais la réponse de LukeH était parfaite pour moi.

Comme le cryptage AES est la norme à utiliser maintenant, il produit une chaîne de base64 (au moins toutes les implémentations de cryptage / décryptage que j’ai vues). Cette chaîne a une longueur en multiples de 4 (ssortingng.length% 4 = 0)

Les chaînes que je recevais étaient contenues + et = au début ou à la fin, et lorsque vous concaténez simplement cela dans la chaîne de requête d’une URL, cela semblera correct (par exemple, dans un email que vous générez), La page .NET la reçoit et la met dans this.Page.Request.QuerySsortingng, ces caractères spéciaux auront disparu et la longueur de votre chaîne ne sera pas un multiple de 4.

Comme il y a des caractères spéciaux sur le FRONT de la chaîne (ex: +), ainsi que = à la fin, vous ne pouvez pas simplement append des = pour compenser la différence lorsque vous modifiez le texte crypté ne correspond pas à ce qui était réellement dans la chaîne de requête originale.

Ainsi, en encapsulant le texte de chiffrement avec HttpUtility.URLEncode (pas HtmlEncode), les caractères non alphanumériques sont transformés de manière à ce que .NET les parsing à leur état d’origine lorsqu’ils sont interprétés dans la collection queryssortingng.

La bonne chose est que nous devons seulement faire le code URLEncode lors de la génération de la chaîne de requête pour l’URL. Du côté entrant, il est automatiquement traduit dans la valeur de la chaîne d’origine.

Voici un exemple de code

 ssortingng cryptossortingng = MyAESEncrypt(MySecretSsortingng); ssortingng URL = WebFunctions.ToAbsoluteUrl("~/ResetPassword.aspx?RPC=" + HttpUtility.UrlEncode(cryptossortingng)); 

Ma première supposition sans connaître les données serait que UserNameToVerify n’est pas un multiple de 4 en longueur. Découvrez le FromBase64Ssortingng sur msdn.

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