web-dev-qa-db-fra.com

base64url en java

http://en.wikipedia.org/wiki/Base64#URL_applications

parle de base64Url - Decode


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 '_'


J'ai créé la fonction suivante:

public static String base64UrlDecode(String input) {
    String result = null;
    BASE64Decoder decoder = new BASE64Decoder();
    try {
        result = decoder.decodeBuffer(input.replace('-','+').replace('/','_')).toString();
    }
    catch (IOException e) {
        System.out.println(e.getMessage());
    }
    return result;
}

il renvoie un très petit ensemble de caractères qui ne ressemblent même pas aux résultats escomptés . des idées?

24
ufk

Avec l'utilisation de Base64 d'Apache Commons, qui peut être configuré pour la sécurité des URL, j'ai créé la fonction suivante:

import org.Apache.commons.codec.binary.Base64;

public static String base64UrlDecode(String input) {
    String result = null;
    Base64 decoder = new Base64(true);
    byte[] decodedBytes = decoder.decode(input);
    result = new String(decodedBytes);
    return result;
}

Le constructeur Base64(true) rend le décodage sûr pour les URL.

22
ufk

Java8 +

import Java.util.Base64;


return Base64.getUrlEncoder().encodeToString(bytes);
48
Boris Treukhov

Base64 encoding fait partie du JDK depuis Java 8. L'encodage sécurisé en URL est également pris en charge.

import Java.nio.charset.StandardCharsets;
import Java.util.Base64;

public String encode(String raw) {
    return Base64.getUrlEncoder()
            .withoutPadding()
            .encodeToString(raw.getBytes(StandardCharsets.UTF_8));
}
18
deamon
6
jontro

Dans le SDK Android, il existe un indicateur dédié dans la classe Base64: Base64.URL_SAFE, utilisez-le comme suit pour le décoder en chaîne:

import Android.util.Base64;
byte[] byteData = Base64.decode(body, Base64.URL_SAFE);
str = new String(byteData, "UTF-8");
5
Oded Breiner
public static byte[] encodeUrlSafe(byte[] data) {
    byte[] encode = Base64.encode(data);
    for (int i = 0; i < encode.length; i++) {
        if (encode[i] == '+') {
            encode[i] = '-';
        } else if (encode[i] == '/') {
            encode[i] = '_';
        }
    }
    return encode;
}

public static byte[] decodeUrlSafe(byte[] data) {
    byte[] encode = Arrays.copyOf(data, data.length);
    for (int i = 0; i < encode.length; i++) {
        if (encode[i] == '-') {
            encode[i] = '+';
        } else if (encode[i] == '_') {
            encode[i] = '/';
        }
    }
    return Base64.decode(encode);
}
5
user249654

Dès le départ, il semble que votre replace() soit en arrière; cette méthode remplace les occurrences du premier caractère par le second, et non l'inverse.

3
Pops

La réponse de @ ufk fonctionne, mais vous n'avez pas besoin de définir l'indicateur urlSafe lorsque vous décodez.

urlSafe est uniquement appliqué aux opérations de codage. Décodage en toute transparence gère les deux modes.

En outre, il existe des aides statiques pour le rendre plus court et plus explicite:

import org.Apache.commons.codec.binary.Base64;
import org.Apache.commons.codec.binary.StringUtils;

public static String base64UrlDecode(String input) {
  StringUtils.newStringUtf8(Base64.decodeBase64(input));
}

Docs

2
overthink

Cette classe peut aider:

import Android.util.Base64;

public class Encryptor {

    public static String encode(String input) {
        return Base64.encodeToString(input.getBytes(), Base64.URL_SAFE);
    }

    public static String decode(String encoded) {
        return new String(Base64.decode(encoded.getBytes(), Base64.URL_SAFE));
    }
}
0
Hadi Note