41

I'm working on a client/server system and I'm trying to do some basic encryption. When I connect to the server, I send a public key as an escaped string across the socket. I've verified that the string is identical on both ends, newlines and all.

On the client (Android), I'm able to use the public/private keys to successfully encrypt and decrypt a secret key (for testing purposes). However, the server fails right out of the gate when trying to decode the public key from a String to a byte[], with:

 java.lang.IllegalArgumentException: Illegal base64 character a

which seems preposterous, as 'a' is absolutely a base64 character, if I understand correctly. The client and server use a shared library to handle all encryption, so the code is nearly identical. The only difference is encoding/decoding base64 Strings, since java.util.Base64 is unavailable on Android.

Shared class

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

...

}

Client (Android) methods

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

}

Server (Linux) methods

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

}

7
  • 5
    try using Base64.NO_WRAP instead of DEFAULT in android Commented Oct 4, 2015 at 16:38
  • Android is the one that's working correctly. Commented Oct 4, 2015 at 16:39
  • 1
    you are encoding it on android right ? if yes then try Base64.NO_WRAP in your encode method on android Commented Oct 4, 2015 at 16:42
  • 1
    Can you show base64str u r trying to decode? Commented Oct 4, 2015 at 16:42
  • 1
    I believe you have formatting issues, its either wrapped or tabbed in some fashion Commented Oct 4, 2015 at 16:43

2 Answers 2

69

On android, Use Base64.NO_WRAP instead of Base64.DEFAULT

@Override
protected String encode(byte[] bytes) {
    return Base64.encodeToString(bytes, Base64.NO_WRAP);
}
Sign up to request clarification or add additional context in comments.

3 Comments

@Mohammad Adil i got a string from server encoded by java.util.Base64 class and i am decoding that string with android.util.base64 that not giving desired result. pls help me
Thanks for Base64.NO_WRAP it's working in my Java backend (using java.util.Base64).
want to do in java. i dont have android. by using java.util.Base64 result is different
13

Instead of Base64.getDecoder() use Base64.getMimeDecoder().

2 Comments

java.util.Base64.getMimeDecoder() call requires API level 26.
Check this link for further explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.