0

I am trying to encript a string in an Android app with a public key that I get from my php server.

php server code:

$res = openssl_pkey_new();
openssl_pkey_export($res, $privKey);

$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];

echo $pubKey;

The server create correctly the key. In my app I store the public key in "response" variable. This var is like: response = "-----BEGIN PUBLIC KEY-----MIIB... etc ...wIDAQAB-----END PUBLIC KEY-----"

Android code:

String pass = "password";
String strEncryInfoData="";
try {
     KeyFactory keyFac = KeyFactory.getInstance("RSA");
     KeySpec keySpec = new X509EncodedKeySpec(Base64.decode(response.trim().getBytes(), Base64.DEFAULT));
     Key publicKey = keyFac.generatePublic(keySpec);

     cipher = Cipher.getInstance("RSA");
     cipher.init(Cipher.ENCRYPT_MODE, publicKey);
     byte[] cipherText = cipher.doFinal(pass.getBytes());
     strEncryInfoData = new String(Base64.encode(cipherText,Base64.DEFAULT));
} catch (Exception e){

}

When I run the application, appear this error: java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag

I don't know why the code doesn't encript the password. Any idea? It is about the encode type? Thanks.

oscargc
  • 305
  • 1
  • 2
  • 11

1 Answers1

0

Try removing the BEGIN header and END footer and all the newlines, then you get the Base64 encoded DER which you need to decode and pass to the X509EncodedKeySpec constructor. Here's some code:

response = response.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");
response = response.replace("\n", "").replace("\r", "");
// Use Base64.NO_WRAP because: https://stackoverflow.com/questions/32935783/java-different-results-when-decoding-base64-string-with-java-util-base64-vs-and/32935972
byte[] responseBytes = Base64.decode(response, Base64.NO_WRAP);
KeySpec keySpec = new X509EncodedKeySpec(responseBytes);
MangaD
  • 315
  • 4
  • 12