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); }
}
Instances of Base64. Encoder class are safe for use by multiple concurrent threads. Unless otherwise noted, passing a null argument to a method of this class will cause a NullPointerException to be thrown.
Basic Encoding and DecodingIt uses the Base64 alphabet specified by Java in RFC 4648 and RFC 2045 for encoding and decoding operations. The encoder does not add any line separator character. The decoder rejects data that contains characters outside the base64 alphabet.
What Does Base64 Mean? Base64 is an encoding and decoding technique used to convert binary data to an American Standard for Information Interchange (ASCII) text format, and vice versa.
On android, Use Base64.NO_WRAP
instead of Base64.DEFAULT
@Override protected String encode(byte[] bytes) { return Base64.encodeToString(bytes, Base64.NO_WRAP); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With