web-dev-qa-db-fra.com

Code pour décoder / encoder une URL base64 modifiée

Je veux encoder en base64 des données pour les mettre dans une URL, puis les décoder dans mon HttpHandler.

J'ai trouvé que encodage en Base64 autorise un caractère '/' qui gâcherait ma correspondance avec UriTemplate. Ensuite, j'ai trouvé qu'il existe un concept de "Base64 modifié pour l'URL" de wikipedia:

Il existe une base64 modifiée pour la variante d'URL, où aucun padding '=' ne sera utilisé, et les caractères '+' et '/' de la base standard sont remplacés respectivement par '-' et '_', de sorte que les encodeurs/décodeurs d'URL n'est plus nécessaire et n'a aucun impact sur la longueur de la valeur codée, laissant la même forme codée intacte pour une utilisation dans les bases de données relationnelles, les formulaires Web et les identificateurs d'objet en général.

Utilisation de .NET Je souhaite modifier mon code actuel en passant de l’encodage et du décodage base64 basiques à l’utilisation de la méthode "modifiée base64 pour URL". Est-ce que quelqu'un a fait ça?

Pour décoder, je sais que ça commence par quelque chose comme:

string base64EncodedText = base64UrlEncodedText.Replace('-', '+').Replace('_', '/');

// Append '=' char(s) if necessary - how best to do this?

// My normal base64 decoding now uses encodedText

Mais, je dois potentiellement ajouter un ou deux caractères '=' à la fin, ce qui semble un peu plus complexe.

Ma logique d'encodage devrait être un peu plus simple:

// Perform normal base64 encoding
byte[] encodedBytes = Encoding.UTF8.GetBytes(unencodedText);
string base64EncodedText = Convert.ToBase64String(encodedBytes);

// Apply URL variant
string base64UrlEncodedText = base64EncodedText.Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');

J'ai vu l'entrée Guid to Base64 for URL StackOverflow, mais sa longueur est connue et ils peuvent donc coder en dur le nombre de signes égaux nécessaires à la fin.

108
Kirk Liemohn

Cela devrait suffire correctement: -

 base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');
63
AnthonyWJones

Vérifiez également la classe HttpServerUtility avec les méthodes UrlTokenEncode et UrlTokenDecode qui gère le codage et le décodage Base64 sécurisés pour les URL.

Remarque 1: le résultat n'est pas une chaîne Base64 valide. Certains caractères non sécurisés pour l'URL sont remplacés.

Note 2: le résultat diffère de l'algorithme base64url dans RFC4648.

///<summary>
/// Base 64 Encoding with URL and Filename Safe Alphabet using UTF-8 character set.
///</summary>
///<param name="str">The origianl string</param>
///<returns>The Base64 encoded string</returns>
public static string Base64ForUrlEncode(string str)
{
    byte[] encbuff = Encoding.UTF8.GetBytes(str);
    return HttpServerUtility.UrlTokenEncode(encbuff);
}
///<summary>
/// Decode Base64 encoded string with URL and Filename Safe Alphabet using UTF-8.
///</summary>
///<param name="str">Base64 code</param>
///<returns>The decoded string.</returns>
public static string Base64ForUrlDecode(string str)
{
    byte[] decbuff = HttpServerUtility.UrlTokenDecode(str);
    return Encoding.UTF8.GetString(decbuff);
}
173
Fredrik Haglund

Pas assez de points à commenter, mais si cela peut aider, l'extrait de code que Sushil a trouvé dans le lien fourni (brouillon JSON Web Signature ietf) fonctionne pour l'encodage de la Base 64 en tant que paramètre dans l'URL.

Extrait copié ci-dessous pour ceux qui sont paresseux:

    static string Base64UrlEncode(byte[] arg)
    {
        string s = Convert.ToBase64String(arg); // Regular base64 encoder
        s = s.Split('=')[0]; // Remove any trailing '='s
        s = s.Replace('+', '-'); // 62nd char of encoding
        s = s.Replace('/', '_'); // 63rd char of encoding
        return s;
    }

    static byte[] Base64UrlDecode(string arg)
    {
        string s = arg;
        s = s.Replace('-', '+'); // 62nd char of encoding
        s = s.Replace('_', '/'); // 63rd char of encoding
        switch (s.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: s += "=="; break; // Two pad chars
            case 3: s += "="; break; // One pad char
            default: throw new System.Exception(
              "Illegal base64url string!");
        }
        return Convert.FromBase64String(s); // Standard base64 decoder
    }
25
Stefan Zvonar

J'ai cliqué ici en cherchant du code pour encoder/décoder pour l'encodage en base64url, ce qui est légèrement différent de celui en base64, comme expliqué dans la question.

Extrait de code c # trouvé dans ce document. brouillon JSON Web Signature ietf

19
Sushil

Par rapport à la réponse acceptée, voici comment vous allez fondamentalement décoder une URL encodée en base64, en utilisant C #:

décoder:

string codedValue = "base64encodedUrlHere";

string decoded;
byte[] buffer =  Convert.FromBase64String(codedValue);
decoded = Encoding.UTF8.GetString(buffer);
5
Chris Halcrow