New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Error in RSA Load PublicKey in XML Format #148

Closed
j796160836 opened this Issue Sep 6, 2013 · 7 comments

Comments

Projects
None yet
4 participants
@j796160836

j796160836 commented Sep 6, 2013

I'm working the RSA connection between C# and PHP.
I found the bug while using XML Format as Public Key.

Here is what I'm tested

  1. I using a working C# RSA example to generate a key pair (XML Format) and paste hard code in PHP.
  2. In PHP, I encrypt a plaintext and decrypt it.
  3. I always got "Decryption error" while using the sample code.

Here is a PrivateKey:

<RSAKeyValue>
 <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
 <P>AN4DDp+IhBca6QEjh4xlm3iexzLajXYrJid6vdWmh4T42nar5nem8Ax39o3ND9b1Zoj41F9zFQmuZ8/AgabreKU=</P>
 <Q>AMQi+R0G9m0K+AcqK3DFpv4RD9jGc0Tle98heNYT7EQvZuuiq4XjvRz0ybqN//bOafrKhsTpRS9DQ7eEpKLI4Bs=</Q>
 <DP>FklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5kX6zk7S0ljKtt2jny2+00VsBerQ==</DP>
 <DQ>AJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2eplU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhM=</DQ>
 <InverseQ>EaiK5KhKNp9SFXuLVwQalvzyHk0FhnNZcZnfuwnlCxb6wnKg117fEfy91eHNTt5PzYPpf+xzD1FnP7/qsIninQ==</InverseQ>
 <D>Fijko56+qGyN8M0RVyaRAXz++xTqHBLh3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxE=</D>
</RSAKeyValue>

And a PublicKey:

<RSAKeyValue>
 <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
</RSAKeyValue>

You can use this simple app to generate
https://github.com/j796160836/RSA_Crypto

The following code has a bug

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$private="............";    // private key paste here
$public=".............";    // public key paste here

$rsa->loadKey($public, CRYPT_RSA_PRIVATE_FORMAT_XML);
$plaintext = 'Hello, World';

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

$ciphertext = base64_encode($rsa->encrypt($plaintext));
//echo $ciphertext;

$rsa->loadKey($private, CRYPT_RSA_PRIVATE_FORMAT_XML);
echo $rsa->decrypt(base64_decode($ciphertext));

?>

I got an error:
Notice: Decryption error in Crypt/RSA.php on line 2225

$rsa->loadKey($public, CRYPT_RSA_PRIVATE_FORMAT_XML);

The bug goes here.


Finally, I Found a workaround on web.
http://www.frostjedi.com/phpbb3/viewtopic.php?f=46&t=168524

Because the XML format of the PrivateKey contains PublicKey.

I use a simply string replace made publicKey to privateKey format

$public = str_replace('</RSAKeyValue>', '<P></P><Q></Q><DP></DP><DQ></DQ><InverseQ></InverseQ><D></D></RSAKeyValue>', $public);

Made publicKey

<RSAKeyValue>
 <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
</RSAKeyValue>

To a patched publicKey :)

<RSAKeyValue>
 <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
  <P></P>
  <Q></Q>
  <DP></DP>
  <DQ></DQ>
  <InverseQ></InverseQ>
  <D></D>
</RSAKeyValue>

then load key with privateKey format and explicitely said load publicKey.

$rsa->loadKey($public, CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->loadKey($rsa->getPublicKey());

Following is a working code:

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$private="<RSAKeyValue>
  <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
  <P>AN4DDp+IhBca6QEjh4xlm3iexzLajXYrJid6vdWmh4T42nar5nem8Ax39o3ND9b1Zoj41F9zFQmuZ8/AgabreKU=</P>
  <Q>AMQi+R0G9m0K+AcqK3DFpv4RD9jGc0Tle98heNYT7EQvZuuiq4XjvRz0ybqN//bOafrKhsTpRS9DQ7eEpKLI4Bs=</Q>
  <DP>FklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5kX6zk7S0ljKtt2jny2+00VsBerQ==</DP>
  <DQ>AJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2eplU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhM=</DQ>
  <InverseQ>EaiK5KhKNp9SFXuLVwQalvzyHk0FhnNZcZnfuwnlCxb6wnKg117fEfy91eHNTt5PzYPpf+xzD1FnP7/qsIninQ==</InverseQ>
  <D>Fijko56+qGyN8M0RVyaRAXz++xTqHBLh3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxE=</D>
</RSAKeyValue>";

$public="<RSAKeyValue>
  <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
</RSAKeyValue>";

$public = str_replace('</RSAKeyValue>', '<P></P><Q></Q><DP></DP><DQ></DQ><InverseQ></InverseQ><D></D></RSAKeyValue>', $public);


$rsa->loadKey($public, CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->loadKey($rsa->getPublicKey());
$plaintext = 'Hello, World';

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

$ciphertext = base64_encode($rsa->encrypt($plaintext));
//echo $ciphertext;

$rsa->loadKey($private, CRYPT_RSA_PRIVATE_FORMAT_XML);
echo $rsa->decrypt(base64_decode($ciphertext));

?>
@terrafrost

This comment has been minimized.

Member

terrafrost commented Sep 6, 2013

<?php
include('Crypt/RSA.php');

$rsa = new Crypt_RSA();
$private="<RSAKeyValue>
 <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
 <P>AN4DDp+IhBca6QEjh4xlm3iexzLajXYrJid6vdWmh4T42nar5nem8Ax39o3ND9b1Zoj41F9zFQmuZ8/AgabreKU=</P>
 <Q>AMQi+R0G9m0K+AcqK3DFpv4RD9jGc0Tle98heNYT7EQvZuuiq4XjvRz0ybqN//bOafrKhsTpRS9DQ7eEpKLI4Bs=</Q>
 <DP>FklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5kX6zk7S0ljKtt2jny2+00VsBerQ==</DP>
 <DQ>AJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2eplU9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhM=</DQ>
 <InverseQ>EaiK5KhKNp9SFXuLVwQalvzyHk0FhnNZcZnfuwnlCxb6wnKg117fEfy91eHNTt5PzYPpf+xzD1FnP7/qsIninQ==</InverseQ>
 <D>Fijko56+qGyN8M0RVyaRAXz++xTqHBLh3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxE=</D>
</RSAKeyValue>";    // private key paste here
$public="<RSAKeyValue>
 <Modulus>AKoYq6Q7UN7vOFmPr4fSq2NORXHBMKm8p7h4JnQU+quLRxvYll9cn8OBhIXq9SnCYkbzBVBkqN4ZyMM4vlSWy66wWdwLNYFDtEo1RJ6yZBExIaRVvX/eP6yRnpS1b7m7T2Uc2yPq1DnWzVI+sIGR51s1/ROnQZswkPJHh71PThln</Modulus>
  <Exponent>AQAB</Exponent>
</RSAKeyValue>";    // public key paste here

$rsa->loadKey($public, CRYPT_RSA_PRIVATE_FORMAT_XML);
$plaintext = 'Hello, World';

$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);

$ciphertext = base64_encode($rsa->encrypt($plaintext));
//echo $ciphertext;

$rsa->loadKey($private, CRYPT_RSA_PRIVATE_FORMAT_XML);
echo $rsa->decrypt(base64_decode($ciphertext));

Works fine for me using the latest Git version. I'm pretty sure the following commit from three months ago fixed this issue:

4de7116

@noren

This comment has been minimized.

noren commented Oct 18, 2013

I have similar issue @terrafrost on php 5.3.10 when is set setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_XML) if I take this out everything works.

<?php

define('DECODING', false);

include('Crypt/RSA.php');

$rsa = new Crypt_RSA();

$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_XML);
$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_XML);

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

$privatekey = encode($key_arrays['privatekey']);
$publickey = encode($key_arrays['publickey']);

file_put_contents('test-private.xml', $privatekey);
file_put_contents('test-public.xml', $publickey);

$plaintext = 'terrafrost';

$privatekey = decode($privatekey);

$publickey = decode($publickey);

$rsa->loadKey($publickey, CRYPT_RSA_PUBLIC_FORMAT_XML);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
echo "Private Key:<BR><pre>$privatekey</pre><br><br>Public Key:<BR><pre>$publickey</pre><BR><BR>";

$ciphertext =  encode($rsa->encrypt($plaintext));

echo "Encrypted message:<BR><pre>$ciphertext</pre><br>";

$rsa->loadKey($privatekey, CRYPT_RSA_PRIVATE_FORMAT_XML);
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
echo $rsa->decrypt(decode($ciphertext));


function encode($string){
    if(DECODING){
        return base64_encode($string);
    }else{
        return $string;
    }
}

function decode($string){
    if(DECODING){
        return base64_decode($string);
    }else{
        return $string;
    }
}
@terrafrost

This comment has been minimized.

Member

terrafrost commented Oct 19, 2013

I tried it with CRYPT_RSA_MODE_OPENSSL and CRYPT_RSA_MODE_INTERNAL with MATH_BIGINTEGER_MODE as MATH_BIGINTEGER_MODE_GMP, MATH_BIGINTEGER_MODE_BCMATH and MATH_BIGINTEGER_MODE_INTERNAL with PHP 5.3.27 and it worked in all cases.

Doesn't look like I can download 5.3.10 that easily, any more, for Windows. The earliest version available for download on 5.3.14 is as follows:

http://www.php.net/releases/

http://museum.php.net/php5/ doesn't have any 5.3 binaries for Windows either and I don't really feel like trying to compile PHP 5.3.10 on VirtualBox in the off chance that it's an issue specific to that version. Maybe you can try out different versions. Is it an issue on 5.3.27 for you? What about PHP 5.5, etc?

Are you using the latest Git version? If not could you also provide me with SSH access? Maybe email terrafrost@php.net or something?

Additionally, maybe post your phpinfo()?

@bantu

This comment has been minimized.

Member

bantu commented Oct 19, 2013

Ubuntu 12.04 LTS has PHP 5.3.10-1ubuntu3.8 and Travis-CI will happily test on PHP 5.3.3 for you.

Or do you think this is a Windows-only issue?

@noren

This comment has been minimized.

noren commented Oct 21, 2013

@terrafrost here is a vagrant box with my example setup: https://bitbucket.org/nemezis/phpseclib-example
just do "vagrant up" in cloned directory and add 192.168.56.200 awesome.dev to your host file.

This is my test environment for that code, if you switch branch from master -> broken then you should see exactly the same error I'm getting.

It is PHP 5.3.10 on ubuntu

If you have any problem with it please feel free to email me.

@terrafrost

This comment has been minimized.

Member

terrafrost commented Oct 24, 2013

Sorry for the delay. Anyway, I think it might work with the latest commit? If you could test and let me know that'd be great.

Thanks!

@noren

This comment has been minimized.

noren commented Oct 25, 2013

Hi, will do and update once reviewed, thanks

@terrafrost terrafrost closed this Nov 20, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment