Java: разные результаты при декодировании base64 строки с java.util.Base64 vs android.util.Base64

Я работаю над клиент-серверной системой, и я пытаюсь сделать базовое шифрование. Когда я подключаюсь к серверу, я посылаю открытый ключ в виде экранированной строки через сокет. Я проверил, что строка идентична на обоих концах, в новых линиях и во всех.

На клиенте (Android) я могу использовать общедоступные/закрытые ключи для успешного шифрования и дешифрования секретного ключа (для целей тестирования). Тем не менее, сервер пытается выйти из строя при попытке декодирования открытого ключа из строки в байт [], причем:

 java.lang.IllegalArgumentException: Illegal base64 character a

который кажется нелепым, поскольку "a" является абсолютно базовым символом, если я правильно понимаю. Клиент и сервер используют общую библиотеку для обработки всего шифрования, поэтому код почти идентичен. Единственное различие заключается в кодировании/декодировании base64 Strings, поскольку java.util.Base64 недоступен на Android.

Общий класс

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);
    }

...

}

Клиентские (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);
    }

}

Сервер (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);
    }

}

Ответы

Ответ 1

В Android-приложении используйте Base64.NO_WRAP вместо Base64.DEFAULT

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

Ответ 2

Вместо Base64.getDecoder() используйте Base64.getMimeDecoder().