3

I am trying to encrypt an AES key with an RSA public key in and Android app and then decrypt the AES key on a server using PHP with phpseclib. I have tested to make sure that the RSA encryption/decryption work on both platforms by encrypting a static text and decrypting it afterwards to check if I still get the original text. According to the test, the RSA code works individually on each platform but there seems to be a difference between the platforms.

In Java, I am using the Bouncy Castle library and have the following code:

RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
new BigInteger("00c897f9e401819e223ffbecc6f715a8d84dce9022762e0e2d54fa434787fcaf230d28bd0c3b6b39b5211f74ffc4871c421362ccfc07ae98b88fa9728f1e26b8210ebbf4981e45867fe810938294d0095d341b646b86dcbd4c246676c203cb1584d01eef0635299714d94fa12933ecd35e6c412573156d9e6e549b7804eb6e165660507d8748bcc8c60da10099bacb94d3f7b50b1883ee108489e0dd97ed7d28e564edd4ee5d6b4225f5c23cdaaf495c3fa08c3b82e1674946e4fa1e79b2493204d6953c261105ba5d0f8dcf3fcd39a51fbc18a5f58ffff169b1bed7ceeded2ae0e8e8e2238e8b77b324d1a482593b1a642e688c860e90d5a3de8515caf384133b", 16),
new BigInteger("11", 16));
keyFactory = KeyFactory.getInstance("RSA", "BC");
//RSAPublicKeySpec rsaKeySpec = new RSAPublicKeySpec(rsaKey.MODULUS, new BigInteger("11", 16));
RSAPublicKey pubKey = (RSAPublicKey)keyFactory.generatePublic(pubKeySpec);  

//Set up the cipher to RSA encryption
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);

// make sure the Aes Key is less than a block size
// otherwise major errors will occur
if(AesKey.length * 8 > pubKey.getModulus().bitLength())
    return "Error: AesKey bigger than block size of RSA Key";

byte[] encryptedKey = cipher.doFinal(AesKey);

// return result Base64 encoded
return Base64.encodeToString(encryptedKey, Base64.DEFAULT);

Then in the PHP, I am using the following code to decrypt the AES key:

$AESkey = base64_decode($AES);

$rsa = new Crypt_RSA();
$private = file_get_contents($_SERVER['DOCUMENT_ROOT'].'/PrivateData/private_key.pem');
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$rsa->loadKey($private);
$AESkey = $rsa->decrypt($AESkey);

When the AES key is being decrypted by the server, I always get the following error: Decryption error in C:\xampp\php\PEAR\phpseclib\Crypt\RSA.php on line 1911. Looking at the code in RSA.php, I think the error has something to do with incorrect padding during encryption but I can't seem to figure out a way to fix it.

Update: I figured out that the above encryption/decryption code is actually correct. The problem I was having was that I did not url encode the output before sending the data from the app to the php so some of the info was being lost.

neubert
  • 14,208
  • 21
  • 90
  • 172
UmangB
  • 55
  • 1
  • 6
  • The error means one of the first two high-order bytes is wrong, and usually indicates a very serious error such as the private key is incorrect. Might there be an endianness issue? That is another thing I would check. – President James K. Polk Jul 01 '11 at 00:44
  • How exactly would I check for that? I have a feeling that there isn't anything wrong with the keys themselves since I can get it to work if I do both the encryption and decryption in PHP but I am thinking it may be a problem with how I input the public key into Java or the padding scheme I use in Java. – UmangB Jul 01 '11 at 22:21
  • One way to check is to reverse the cipher bytes and see if decryption succeeds. But the best way is to find some known good test vectors and see how they are processed by the PHP side. It would also help if you could set breakpoints in the phpseclib to examine intermediate values. – President James K. Polk Jul 01 '11 at 22:54

1 Answers1

0

Which version of phpseclib are you using? Depending on the version the following may help:

http://www.frostjedi.com/phpbb/viewtopic.php?p=118414#p118414

  • I have the most up to date version that includes the fix discussed in the link. After doing some further testing, I have determined that this may be a problem with the different character sets used by java and php. Java uses UTF-8 by default and PHP uses ISO-8859-1 by default. I am not sure how to convert between the two without losing any of the data. I also cannot figure out how to make php base 64 decode utf-8 strings. – UmangB Jul 06 '11 at 02:40
  • What if you didn't generate the password as a String in Java but rather as a ByteArray or something? –  Jul 06 '11 at 22:07
  • actually, after doing a bunch of tests and debugging to find a solution, I found out that the encryption is correct but the information send between the android app and php has to be url encoded after it has been base 64 encoded or else the data gets messed up. – UmangB Jul 08 '11 at 02:47