Daniel
Daniel

Reputation: 598

Convert CRYPT_RSA_PUBLIC_FORMAT_PKCS1 from php to RSA Public key in Java

I'm trying to send a RSA Public Key from PHP to Java(Android). My PHP code looks something like this:

function __construct() {
        $rsa = new Crypt_RSA();
        $rsa->setHash('sha1');
        $rsa->setMGFHash('sha1');
        $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);
        $rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
        $rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);

        // Code to Generate the public key and private key

        $keys = $rsa->createKey(1024);

        extract($keys);

        // Base 64 encode Public and Private key
        $this->rsa = $rsa;
        $this->keys = $keys;
        $this->publicKeyBase = base64_encode($publickey);
        $this->privateKeyBase = base64_encode($privatekey);
}

And I send $this->publicKeyBase to my Android app. In Java I get the encoded string like this:

LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tDQpNSUdKQW9HQkFMQzluUkdhVGsybzlJTW5YVW0vWWRVMHMrTFplc09GUi9VYkU2K21hWDlwbGIwRW11RzZacHBMDQpoV2dRbUNBYmV6aW9ScHZNL0lVZHZWczZ6ZmFKaDRGTnFaRXo0cWd0V0ovaFpUU2RudlFIMlI3cWF0TEY0c0ZSDQpDbWNNVDZBdnYvdDJnR1liMW4vY1lhb01ralNOd1RFdTJBSU45djg0Skk2ZWhmOGNST0RMQWdNQkFBRT0NCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0=

And after decoding it, it looks something like this:

-----BEGIN RSA PUBLIC KEY-----
    MIGJAoGBALC9nRGaTk2o9IMnXUm/YdU0s+LZesOFR/UbE6+maX9plb0EmuG6ZppL
    hWgQmCAbezioRpvM/IUdvVs6zfaJh4FNqZEz4qgtWJ/hZTSdnvQH2R7qatLF4sFR
    CmcMT6Avv/t2gGYb1n/cYaoMkjSNwTEu2AIN9v84JI6ehf8cRODLAgMBAAE=
    -----END RSA PUBLIC KEY-----

How do I convert this to a pubic key that can be used in the Android App. Have seen lots of examples online but they aren't working and my java code(below) also seems not to work. Any possible solutions?

private static PublicKey getPublicKeyFromPemFormat(String PEMString, boolean isFilePath) throws IOException, NoSuchAlgorithmException,
            InvalidKeySpecException {

        BufferedReader pemReader = null;
        if (isFilePath) {
            pemReader = new BufferedReader(new InputStreamReader(
                    new FileInputStream(PEMString)));
        } else {
            pemReader = new BufferedReader(new InputStreamReader(
                    new ByteArrayInputStream(PEMString.getBytes("UTF-8"))));
        }
        StringBuffer content = new StringBuffer();
        String line = null;

        while ((line = pemReader.readLine()) != null) {
            if (line.indexOf("-----BEGIN RSA PUBLIC KEY-----") != -1) {
                while ((line = pemReader.readLine()) != null) {
                    if (line.indexOf("-----END RSA PUBLIC KEY-----") != -1) {
                        break;
                    }
                    content.append(line.trim());
                }
                break;
            }
        }
        if (line == null) {
            throw new IOException("PUBLIC KEY" + " not found");
        }
        Log.i("PUBLIC KEY: ", "PEM content = : " + content.toString());

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decode(content.toString(), Base64.DEFAULT)));

    }

new X509EncodedKeySpec(Base64.decode(content.toString(), Base64.DEFAULT)) throws an Invalid KeySpec Exception.

Upvotes: 0

Views: 566

Answers (1)

President James K. Polk
President James K. Polk

Reputation: 41967

The documentation is a little confusing, but by looking at the source code for method _convertPublicKey($n, $e) starting at line 950 it appears that if $publicKeyFormat == PUBLIC_FORMAT_PKCS8 then the output format should be one that is compatible with Java's X509EncodedKeySpec class.

Upvotes: 2

Related Questions