Nirav Chhatrola Nirav Chhatrola - 11 months ago 110
Java Question

RSA public key generation issue (PHP/Java integration)

I have one server and one client.

Client might be in different technologies like java , php.

server code is written in java.

What I am doing in server is, get exponent and modulus bytes of client public key and generate public key of client.
To generate client public key I am using the code below:

RSAPublicKeySpec spec = new RSAPublicKeySpec(modulusBigInt,exponentBigInt);
keyFactory = KeyFactory.getInstance("RSA", "BC");
RSAPublicKey clientPublicKey = (RSAPublicKey) keyFactory.generatePublic(spec);

To encrypt data using client public key I am using below code:

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, clientPublickey);
scrambled = cipher.doFinal(buffer);

Server Information

I have implemented RSA-1024 to encrypt AES key.
I am using RSA/ECB/PKCS1Padding algorithm. and I have also make sure that all clients have also consider 1 padding in their code.

Client - 1 (Java)

If client is also made in java than public key is successfully generated from exponent and modulus of client public key.
I am using the code below to generate key pair of client RSA key..

keyPairGene = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyPairGene.genKeyPair();
RSAPublicKey clientPublickey = (RSAPublicKey) keyPair.getPublic();

Client -2 (php)

Now the problem is if client is in php .. than public key is successfully generated but when I try to encrypt using that public key at that time bad padding exception occurs when I have used default provider in server.
I am using bellow code to generate key pair of client RSA key..

$options = array('private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'config' => realpath(__DIR__) . '/openssl.cnf');

#Generates New Private / Public Key Pair
$pkGenerate = openssl_pkey_new($options);
#Get Client Private Key
openssl_pkey_export($pkGenerate, $PrivateKey, NULL, $options);
#Get Client Public Key
$keyData = openssl_pkey_get_details($pkGenerate);

Than I have tried BC provider ... It gives me the exception below:

org.bouncycastle.crypto.DataLengthException: input too large for RSA cipher.

I am not getting what is the problem occurs when I am trying to generate public key from exponent and modulus when client is in php...
if client is in java than its no issues.... and works perfectly..

Any type of help is welcome...

What I have observed from debugging code is ,
client's public key modulus byte's bit length at server side is varies between 1020 to 1023... it never reaches at 1024 though we have define size as 1024.

Answer Source

Still don't get what exactly the problem is...
but I have implemented work around for it...

I got stuck in generating public key of client using exponent and modulus.
So now I have used one standard format of public key certificate - DER & PEM.

What I did is, generated DER or PEM from PHP side using bellow code,

$options = array('private_key_bits' => 1024,
            'private_key_type' => OPENSSL_KEYTYPE_RSA,
            'config' => realpath(__DIR__) . '/openssl.cnf');

        #Get Client Public Key  
        $keyData = openssl_pkey_get_details($pkGenerate);
        $clientPublicKey = $keyData['key'];
        $this->clientData['clientPublicKeyPEM'] = $keyData['key'];

And then send that generated PEM to Server (Java).
And at server side I have developed bellow code to regenerate Public key from POM string.

     KeyFactory keyFactory=KeyFactory.getInstance("RSA");
     byte[] pubKeyBits = Base64.decodeBase64(clientPublickeyView.getModulusBytes());
     PublicKey pubKey=keyFactory.generatePublic(new X509EncodedKeySpec(pubKeyBits));