Je souhaite obtenir le codage sécurisé en base CURL des URL Base64. En Java, nous avons la bibliothèque Codec
commune qui me donne une chaîne encodée sécurisée par une URL. Comment puis-je obtenir la même chose avec C #?
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode");
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
Le code ci-dessus le convertit en Base64, mais il compresse ==
. Existe-t-il un moyen d'obtenir un codage sécurisé des URL?
Il est commun de simplement échanger l'alphabet pour une utilisation dans les URL, de sorte qu'aucun codage% n'est nécessaire; seuls 3 des 65 caractères posent problème - +
, /
et =
. les remplacements les plus courants sont -
à la place de +
et _
à la place de /
. En ce qui concerne le remplissage: il suffit de le supprimer (le =
); vous pouvez déduire la quantité de rembourrage nécessaire. À l'autre bout: inversez le processus:
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes)
.TrimEnd(padding).Replace('+', '-').Replace('/', '_');
avec:
static readonly char[] padding = { '=' };
et inverser:
string incoming = returnValue
.Replace('_', '/').Replace('-', '+');
switch(returnValue.Length % 4) {
case 2: incoming += "=="; break;
case 3: incoming += "="; break;
}
byte[] bytes = Convert.FromBase64String(incoming);
string originalText = Encoding.ASCII.GetString(bytes);
La question intéressante, cependant, est: est-ce la même approche que celle utilisée par la "bibliothèque de codecs commune"? Ce serait certainement une première chose raisonnable de tester - c'est une approche assez commune.
Vous pouvez utiliser la classe Base64UrlEncoder
de l'espace de noms Microsoft.IdentityModel.Tokens
.
const string StringToEncode = "He=llo+Wo/rld";
var encodedStr = Base64UrlEncoder.Encode(StringToEncode);
var decodedStr = Base64UrlEncoder.Decode(encodedStr);
if (decodedStr == StringToEncode)
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 apportées, avec quelques améliorations de performances, nous avons publié une implémentation très facile à utiliser url-safe base64 dans NuGet avec le code source disponible sur GitHub (sous licence MIT).
L'utilisation est aussi simple que
var bytes = Encoding.UTF8.GetBytes("Foo");
var encoded = UrlBase64.Encode(bytes);
var decoded = UrlBase64.Decode(encoded);
Si vous utilisez ASP.NET Core, vous pouvez également utiliser Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode
.
Si vous n'utilisez pas ASP.NET Core, la source WebEncoders
est disponible sous Apache 2.0 License .
Utilisation du moteur de cryptographie Microsoft dans UWP.
uint length = 32;
IBuffer buffer = CryptographicBuffer.GenerateRandom(length);
string base64Str = CryptographicBuffer.EncodeToBase64String(buffer)
// ensure url safe
.TrimEnd('=').Replace('+', '-').Replace('/', '_');
return base64Str;
Voici une autre méthode pour décoder une base64 sécurisée pour l’URL qui a été encodée de la même manière avec Marc. Je ne comprends tout simplement pas pourquoi 4-length%4
a fonctionné (cela fonctionne).
Comme suit, seules les longueurs de bits de l’Origine sont communes à 6 et 8, base64 n’ajoutant 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
"==" "="
Nous pouvons donc le faire à l'inverse, si la longueur en bits du résultat ne peut pas être divisible par 8, elle a été ajoutée:
base64String = base64String.Replace("-", "+").Replace("_", "/");
var base64 = Encoding.ASCII.GetBytes(base64String);
var padding = base64.Length * 3 % 4;//(base64.Length*6 % 8)/2
if (padding != 0)
{
base64String = base64String.PadRight(base64String.Length + padding, '=');
}
return Convert.FromBase64String(base64String);