Comment obtenir un encodage sécurisé de l’URL Base64 en C #?

Je veux obtenir un encodage sûr de l’URL Base64 en C #. En Java, nous avons la bibliothèque commune Codec qui me donne une chaîne encodée en URL sécurisée. Comment puis-je obtenir la même chose en utilisant C #?

 byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("SsortingngToEncode"); ssortingng returnValue = System.Convert.ToBase64Ssortingng(toEncodeAsBytes); 

Le code ci-dessus le convertit en Base64, mais il compresse == . Existe-t-il un moyen de parvenir à un encodage sécurisé des URL?

Il est fréquent de simplement échanger l’alphabet pour l’utiliser dans des URL, de sorte qu’aucun codage% n’est nécessaire; Seulement 3 des 65 caractères sont problématiques – + , / et = . les remplacements les plus courants sont - à la place de + et _ à la place de / . En ce qui concerne le padding: il suffit de le retirer (le = ); vous pouvez déduire la quantité de rembourrage nécessaire. À l’autre extrémité: inversez simplement le processus:

 ssortingng returnValue = System.Convert.ToBase64Ssortingng(toEncodeAsBytes) .TrimEnd(padding).Replace('+', '-').Replace('/', '_'); 

avec:

 static readonly char[] padding = { '=' }; 

et inverser:

 ssortingng incoming = returnValue .Replace('_', '/').Replace('-', '+'); switch(returnValue.Length % 4) { case 2: incoming += "=="; break; case 3: incoming += "="; break; } byte[] bytes = Convert.FromBase64Ssortingng(incoming); ssortingng originalText = Encoding.ASCII.GetSsortingng(bytes); 

La question intéressante, cependant, est la suivante: est-ce la même approche que la “bibliothèque de codec commune” utilise? Ce serait certainement une première chose raisonnable à tester – c’est une approche assez courante.

Vous pouvez utiliser la classe Base64UrlEncoder partir de l’espace de noms Microsoft.IdentityModel.Tokens .

 const ssortingng SsortingngToEncode = "He=llo+Wo/rld"; var encodedStr = Base64UrlEncoder.Encode(SsortingngToEncode); var decodedStr = Base64UrlEncoder.Decode(encodedStr); if (decodedStr == SsortingngToEncode) Console.WriteLine("It works!"); else Console.WriteLine("Dangit!"); 

Utilisez System.Web.HttpServerUtility.UrlTokenEncode (octets) pour coder et System.Web.HttpServerUtility.UrlTokenDecode (octets) pour décoder.

Sur la base des réponses apscopes ici avec quelques améliorations de performances, nous avons publié une implémentation de base64 sécurisée par url très facile à utiliser avec NuGet avec le code source disponible sur GitHub (licence MIT).

L’utilisation est aussi simple que

 var bytes = Encoding.UTF8.GetBytes("Foo"); var encoded = UrlBase64.Encode(bytes); var decoded = UrlBase64.Decode(encoded); 

Une autre option, si vous utilisez ASP.NET Core, serait d’utiliser Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode .

Si vous n’utilisez pas ASP.NET Core, la source WebEncoders est disponible sous la licence Apache 2.0 .

Voici une autre méthode pour décoder une base64 sécurisée par URL qui était encodée de la même manière avec Marc. Je ne comprends tout simplement pas pourquoi 4-length%4 fonctionné (c’est le cas).

Comme suit, seule la longueur en bits de l’origine est un multiple commun de 6 et 8, la base64 n’ajoute pas “=” au résultat.

 1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8 1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6 "==" "=" 

On peut donc le faire en sens inverse, si la longueur du bit du résultat ne peut être divisible par 8, il a été ajouté:

 base64Ssortingng = base64Ssortingng.Replace("-", "+").Replace("_", "/"); var base64 = Encoding.ASCII.GetBytes(base64Ssortingng); var padding = base64.Length * 3 % 4;//(base64.Length*6 % 8)/2 if (padding != 0) { base64Ssortingng = base64Ssortingng.PadRight(base64Ssortingng.Length + padding, '='); } return Convert.FromBase64Ssortingng(base64Ssortingng); 

Utilisation du moteur cryptographique Microsoft dans UWP.

 uint length = 32; IBuffer buffer = CryptographicBuffer.GenerateRandom(length); ssortingng base64Str = CryptographicBuffer.EncodeToBase64Ssortingng(buffer) // ensure url safe .TrimEnd('=').Replace('+', '-').Replace('/', '_'); return base64Str;