Interoperability phpseclib and Java

Get help with using the PHP Secure Communications Library.

Moderator: Nuxius

Forum rules
The purpose of this forum is to provide support for phpseclib, a pure PHP SSH / SFTP / RSA library.

Posts by new users are held in a moderation queue and are not publicly visible until the post is approved.

Interoperability phpseclib and Java

Postby grooveliker » Wed Aug 21, 2013 8:44 am

Hi,

I try to encrypt a small text phrase using phpseclib that shall be decrypted by a Java program using the internal javax.crypto package. Unfortunately it doesn’t work.
I used phpseclib to generate the key pair and extracted the modulus and exponent of the public key to use it in Java. Then I used phpseclib with the private key to encrypt a string. In Java I used the public key to decrypt the encrypted text. Unfortunately I get the following error in Java:

javax.crypto.BadPaddingException: Blocktype mismatch: 68
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:328)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:272)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:349)

Pease find below the php and Java code if this helps to discuss the problem.

PHP code to generate the keys:

Code: Select all
$rsa = new Crypt_RSA();
$rsa->setPrivateKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_RAW);
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_RAW);
extract($rsa->createKey(1024));
   
echo "Public key<br/>";
echo "modulus: " . $publickey["n"];
echo "<br/>";
echo "exponent:" . $publickey["e"];
echo "<br/><br/>";
   
echo "Private key<br/>";
echo $privatekey;


The PHP code to encrypt the text:

Code: Select all
$rsa = new Crypt_RSA();
$plaintext = 'terrafrost';
 
$rsa->loadKey("<private key>");
$ciphertext = $rsa->encrypt($plaintext);
echo base64_encode($ciphertext);


The Java code looks like:

Code: Select all
String encryptedText = "<copy paste from php output>";
BASE64Decoder decoder = new BASE64Decoder();
byte[] encryptedData = decoder.decodeBuffer(encryptedText);

BigInteger m = new BigInteger(<modulus of public key>);
BigInteger e = new BigInteger(<exponent of public key>);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
byte[] decodedData = cipher.doFinal(encryptedData);
String decodedString = new String(decodedData, "UTF-8");
LOG.debug("decoded: " + decodedString);


By the way I got one general question: why do I get a different encryption string each time I run the php script although I use the same text and the same private key on each run? I would expect to get the same encrypted string each time, at least this is what java does if I encrypt a string with RSA.

Any help is appreciated.

Regards.
grooveliker
Traveler
 
Posts: 1
Joined: Wed Aug 21, 2013 7:55 am

Re: Interoperability phpseclib and Java

Postby TerraFrost » Wed Aug 21, 2013 6:24 pm

phpseclib uses OAEP padding by default. PKCS1 padding is more common albeit a little less secure. To use PKCS1 padding do this:

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

By the way I got one general question: why do I get a different encryption string each time I run the php script although I use the same text and the same private key on each run? I would expect to get the same encrypted string each time, at least this is what java does if I encrypt a string with RSA.

Both OAEP padding and PKCS1 padding use randomized padding. Like with both the length of text you can encrypt to the modulo. With PKCS1 it's 11 bytes less than the modulo. The extra 11 bytes are for randomized padding. Which you want so that known plaintext attacks can't be utilized.

It's surprising that Java would be giving you the same output each time. Maybe it's not using any padding at all? idk
TerraFrost
Legendary Guard
 
Posts: 12357
Joined: Wed Dec 04, 2002 6:37 am


Return to phpseclib support

Who is online

Users browsing this forum: No registered users and 3 guests

cron