web-dev-qa-db-fra.com

Java: résultats différents lors du décodage de la chaîne base64 avec Java.util.Base64 vs Android.util.Base64

Je travaille sur un système client/serveur et j'essaie de faire un chiffrement de base. Lorsque je me connecte au serveur, j'envoie une clé publique sous forme de chaîne d'échappement à travers le socket. J'ai vérifié que la chaîne est identique aux deux extrémités, aux sauts de ligne et à tous.

Sur le client (Android), je peux utiliser les clés publiques/privées pour chiffrer et déchiffrer avec succès une clé secrète (à des fins de test). Cependant, le serveur échoue dès la sortie de la porte lorsqu'il essaie de décoder la clé publique d'une chaîne en un octet [], avec:

 Java.lang.IllegalArgumentException: Illegal base64 character a

ce qui semble absurde, car "a" est absolument un caractère base64, si je comprends bien. Le client et le serveur utilisent une bibliothèque partagée pour gérer tout le cryptage, de sorte que le code est presque identique. La différence uniquement est le codage/décodage des chaînes base64, car Java.util.Base64 n'est pas disponible sur Android.

Classe partagée

public abstract class EasyCrypt {

...

    public PublicKey loadPublicKey(String key64) throws GeneralSecurityException {

        byte[] data = decode(key64); //Calls abstract methods, shown below

        X509EncodedKeySpec spec = new X509EncodedKeySpec(data);
        KeyFactory fact = KeyFactory.getInstance("RSA");
        return fact.generatePublic(spec);
    }

...

}

Méthodes client (Android)

import Android.util.Base64;

public class ClientCrypt extends EasyCrypt {
    @Override
    protected byte[] decode(String s) {
        return Base64.decode(s.getBytes(), Base64.DEFAULT); //Works perfectly
    }

    @Override
    protected String encode(byte[] bytes) {
        return Base64.encodeToString(bytes, Base64.DEFAULT);
    }

}

Méthodes serveur (Linux)

import Java.util.Base64;

public class ServerCrypt extends EasyCrypt{
    @Override
    public byte[] decode(String str){
        return Base64.getDecoder().decode(str); //Throws IllegalArgumentException
    }

    @Override
    public String encode(byte[] bytes){
        return Base64.getEncoder().encodeToString(bytes);
    }

}

25
Parker Kemp

Sur Android, utilisez Base64.NO_WRAP au lieu de Base64.DEFAULT

@Override
protected String encode(byte[] bytes) {
    return Base64.encodeToString(bytes, Base64.NO_WRAP);
}
42
Mohammad Adil

Au lieu de Base64.getDecoder() utilisez Base64.getMimeDecoder().

9
S Shepard