1

I used phpseclib to generate RSA public and private key.

$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);
extract($rsa->createKey(2048));  

Then i used these two keys in my android app to encrypt/decrypt data.

public static final String publicKey = "MIIBIjANBgk......DAQAB";
public static final String privateKey = "MIIEpAI......Zh+0bQ==";  

I can encrypt data in JAVA with public key and decrypt that data in PHP with private key.
This works fine,

public static String encryptData(String data) {
    String ret = null;
    try {
        PublicKey key = KeyFactory.getInstance("RSA").generatePublic(
                new X509EncodedKeySpec(Base64.decode(publicKey, Base64.DEFAULT)));

        Cipher cph = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cph.init(Cipher.ENCRYPT_MODE, key);
        ret = Base64.encodeToString(cph.doFinal(data.getBytes()),
                Base64.DEFAULT);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    }
    return ret;
}

PHP Part

$rsa = new Crypt_RSA();
$rsa->loadKey($privatekey);
echo $rsa->decrypt($encrypted);

But when i try to decrypt the same encrypted message in java by this function,

public static String decryptData(String data) {
    String ret = null;
    try {
        PrivateKey key = KeyFactory.getInstance("RSA").generatePrivate(
                new PKCS8EncodedKeySpec(Base64.decode(privateKey, Base64.DEFAULT)));

        Cipher cph = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cph.init(Cipher.DECRYPT_MODE, key);
        ret = Base64.encodeToString(cph.doFinal(data.getBytes()),
                Base64.DEFAULT);
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    }
    return ret;
}

I get this error,

06-05 11:48:26.854: W/System.err(1311): java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
06-05 11:48:26.862: W/System.err(1311):     at com.android.org.conscrypt.OpenSSLKey.getPrivateKey(OpenSSLKey.java:136)
06-05 11:48:26.862: W/System.err(1311):     at com.android.org.conscrypt.OpenSSLRSAKeyFactory.engineGeneratePrivate(OpenSSLRSAKeyFactory.java:64)
06-05 11:48:26.866: W/System.err(1311):     at java.security.KeyFactory.generatePrivate(KeyFactory.java:186)

Please help. And sorry for the lengthy question.

palatok
  • 1,022
  • 5
  • 20
  • 30

1 Answers1

2

Try this branch of phpseclib:

https://github.com/terrafrost/phpseclib/tree/pkcs8/phpseclib

And instead of $rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1); do $rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);

The thing is... Java is expecting a PKCS8 key. A PKCS8 key starts with -----BEGIN PRIVATE KEY----- instead of -----BEGIN RSA PRIVATE KEY-----.

neubert
  • 15,947
  • 24
  • 120
  • 212
  • I used the above library and also used PKCS8 but my PHP script still generate private key with " -----BEGIN RSA PRIVATE KEY----- " at beginning :( – palatok Jun 13 '14 at 08:09
  • Try doing `echo $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PKCS8);` – neubert Jun 13 '14 at 12:05
  • echo $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PKCS8); doesn't output anything , but echo $publickey."

    ".$privatekey."

    "; outputs the keys like before.
    – palatok Jun 13 '14 at 12:34
  • Oh right - that's only for converting keys and you're trying to create one from scratch. Anyway, doing the replacement I suggested in my orig post worked for me with the code from that branch. Maybe you're not on that branch. If so just try replacing your Crypt/RSA.php with this: https://github.com/terrafrost/phpseclib/blob/0a5e26a648d187c1568fa2bcee0ffff134000489/phpseclib/Crypt/RSA.php Here's my code: http://pastebin.com/snkmTQ7k – neubert Jun 13 '14 at 13:12
  • Thanks , that last thing worked. But now i need another help from you. I generated public/private key by one script and then used them to decrypt data by another script. But the decryption is not working $rsa->decrypt() returns false . my code : http://pastebin.com/N1AFw1ZX – palatok Jun 13 '14 at 14:20
  • Maybe try commenting out `$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_OAEP);`? Failing that... I'll try to write some debug code that can maybe be used to diagnose what's going on. – neubert Jun 13 '14 at 18:59