1

I'm trying to convert key pair from PEM format :

-----BEGIN PUBLIC KEY----- 

-----END PUBLIC KEY-----

Into XML format :

<RSAKeyValue>
<Exponent> </Exponent>
<Modulus> </Modulus>
</RSAKeyValue>

Is it possible using only openssl as I generate the keys through it ?

nb : my keys are stored into $privKey and $pubKey variable for test purpose, so I want to be able to $echo the XML format key and not store it into a file for the moment.

nb' : I have tried using phpseclib with an exemple found here but it gives me this error "Uncaught Error: Class "BaseController" not found in ..."

Thanks for your help

Here is the PHP code :

<?php

$config = array
(
    'config' => 'C:\xampp\htdocs\crypto\openssl.cnf',
    'default_md' => 'sha512',
    'private_key_bits' => 4096,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
);

$keypair = openssl_pkey_new($config);

openssl_pkey_export($keypair, $privKey, null, $config);

$publickey = openssl_pkey_get_details($keypair);
$pubKey = $publickey['key'];

use phpseclib3\Crypt\RSA;
echo $pubKey->toString("XML");
echo "$privKey";

?>
Topaco
  • 40,594
  • 4
  • 35
  • 62
  • Anyone to help me ? – Ethernet3003 Jun 01 '22 at 06:01
  • `BaseController` isn't needed for the key import/export. Which version of *phpseclib* do you have installed? – Topaco Jun 01 '22 at 06:37
  • @Topaco, hi, I generate the key using openSSL but the output format is in PEM and I would like to have it in XML, that's why I'm trying to use phpseclib to convert it from PEM to XML. I'm using phpseclib3 downloaded from github – Ethernet3003 Jun 01 '22 at 06:46
  • Where is the problem? The conversion is a two-liner. Post your code. – Topaco Jun 01 '22 at 06:55
  • @Topaco just posted it down and I get "Uncaught Error: Call to a member function toString() on string", I never did PHP in my life, it might be a simple issue – Ethernet3003 Jun 01 '22 at 07:19
  • Your answer is not an answer, please delete it, edit your question and post the code there. You can't combine openssl and phpseclib in this way, of course. Also the key import has to be done with phpseclib. – Topaco Jun 01 '22 at 07:22
  • @Topaco So I need to generate the key pair using phpseclib instead of openSSL then ? Is there a way to only use openSSL for that ? If not can you point me to a ressource where I can see how to generate the key pair using phpseclib, is phpseclib as safe, reliable and fast as openSSL for generating key pair ? thanks for your time – Ethernet3003 Jun 01 '22 at 07:29
  • @Topaco I just saw that phpseclib have the option to get the output format to XML but when I try the code given on their website I get this error "Uncaught Error: Class "phpseclib3\Crypt\Common\AsymmetricKey" not found in C:\xampp\htdocs\phpseclib3\Crypt\RSA.php:69 Stack trace: #0" what should I do ? – Ethernet3003 Jun 01 '22 at 08:00
  • You can use OpenSSL for key generation, but you have to import the PEM key in the phpseclib part. Alternatively you can generate the key with phpseclib. See my answer. – Topaco Jun 01 '22 at 08:00
  • @Topaco thanks for your answer, the code is very clear to me now, idk how to thank you, I can't even give you a +1 reputation. However, as the noob I am I have an error "Uncaught Error: Class "phpseclib3\Crypt\RSA" not found in C:\xampp\htdocs\test.php:5", I put the phpseclib folder inside xampp and inside htdocs but I still get the error, What is the problem ? – Ethernet3003 Jun 01 '22 at 08:18
  • Even as a new member you should at least be able to accept answers (regarding upvoting I'm not sure if you need to have a minimum reputation). Concerning your installation/configuration problem: installations/configurations are platform dependent and since I don't know the details of your environment, I unfortunately can't help you. But you can ask a new question if you don't find a suitable answer to the problem on SO. – Topaco Jun 01 '22 at 08:30
  • @Topaco If by accepting new answers you mean clicking on the approval sign, it's done, Thanks again for your time and patience with me, have a good day. I'll post a new question regarding the configuration. You really know your stuff, I respect that. – Ethernet3003 Jun 01 '22 at 08:38
  • @Topaco, I made everything to install phpseclib though composer and did everything like other stackoverflow issue, but It keeps throwing me error when I try to run the code you answered me, what is your setup to make the code below run properly ? help me please – Ethernet3003 Jun 02 '22 at 05:15
  • @Topaco 1) I went the the htdocs path with my cmd | 2) i did composer require phpseclib/phpseclib:~3.0 | 3) I did the right autload setup | 4) I ran the SAME code that you gave | 5) Error : Class phpseclib\Crypt\RSA not found It won't work, tried for 10+ hours, why making a lib if it's so difficult to use, i'm desparate – Ethernet3003 Jun 02 '22 at 06:12
  • Please post a new question with all the information needed to answer, e.g. failed code, stack trace, detailed description of the environment and installation, etc. This is not possible via comments and is also beyond the scope of this question. – Topaco Jun 02 '22 at 06:30
  • I've rejected your changes because the `$config` array modifications affect installation/configuration of OpenSSL and are not important to the actual problem (key import/export). The code is supposed to be executable for future readers, which would not be the case with your environment-specific changes (like the path definition). Please understand. I have added comments to the affected part for better comprehension and commented out the private key export, as it's not required for this example. – Topaco Jun 03 '22 at 08:28
  • @Topaco Okay, It was the working way for me I though it was a good improvement, I made it works, everything is working fine now with your help, Thanks again mate :) – Ethernet3003 Jun 03 '22 at 19:57

1 Answers1

0

The conversion of a PEM encoded key in X.509/SPKI format to XML format can be done with phpseclib as follows:

use phpseclib3\Crypt\PublicKeyLoader;

$x509pem = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAunF5aDa6HCfLMMI/MZLT
5hDk304CU+ypFMFiBjowQdUMQKYHZ+fklB7GpLxCatxYJ/hZ7rjfHH3Klq20/Y1E
bYDRopyTSfkrTzPzwsX4Ur/l25CtdQldhHCTMgwf/Ev/buBNobfzdZE+Dhdv5lQw
KtjI43lDKvAi5kEet2TFwfJcJrBiRJeEcLfVgWTXGRQn7gngWKykUu5rS83eAU1x
H9FLojQfyia89/EykiOO7/3UWwd+MATZ9HLjSx2/Lf3g2jr81eifEmYDlri/OZp4
OhZu+0Bo1LXloCTe+vmIQ2YCX7EatUOuyQMt2Vwx4uV+d/A3DP6PtMGBKpF8St4i
GwIDAQAB
-----END PUBLIC KEY-----';

$publicKey = PublicKeyLoader::load($x509pem);   // import public PEM key
$xmlFormattedKey = $publicKey->toString("XML"); // export public XML key
print($xmlFormattedKey);

The output is:

<RSAKeyValue>     
    <Modulus>unF5aDa6HCfLMMI/MZLT5hDk304CU+ypFMFiBjowQdUMQKYHZ+fklB7GpLxCatxYJ/hZ7rjfHH3Klq20/Y1EbYDRopyTSfkrTzPzwsX4Ur/l25CtdQldhHCTMgwf/Ev/buBNobfzdZE+Dhdv5lQwKtjI43lDKvAi5kEet2TFwfJcJrBiRJeEcLfVgWTXGRQn7gngWKykUu5rS83eAU1xH9FLojQfyia89/EykiOO7/3UWwd+MATZ9HLjSx2/Lf3g2jr81eifEmYDlri/OZp4OhZu+0Bo1LXloCTe+vmIQ2YCX7EatUOuyQMt2Vwx4uV+d/A3DP6PtMGBKpF8St4iGw==</Modulus>
    <Exponent>AQAB</Exponent>
</RSAKeyValue>

For key generation OpenSSL can be used as in your code. However, the exported PEM key must be imported in the phpseclib part as shown in the code above (this import is missing in your code):

// Key generation with OpenSSL
$config = array(
    "private_key_bits" => 2048,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);

$res = openssl_pkey_new($config);                // create key resource using $config 
//openssl_pkey_export($res, $privKey);           // export private key (PEM encoded, PKCS#8 format); not required for this example
$pubKeyDetails = openssl_pkey_get_details($res);
$x509pem = $pubKeyDetails["key"];                // export public key (PEM encoded, X.509 format)

// Key conversion with phpseclib
$publicKey = PublicKeyLoader::load($x509pem);   // import public PEM key generated with OpenSSL
$xmlFormattedKey = $publicKey->toString("XML"); // export public XML key 
print($xmlFormattedKey);

Alternatively, also key generation can be done with phpseclib:

use phpseclib3\Crypt\RSA;

$privateKey = RSA::createKey(2048);                              // generate private key
$xmlFormattedKey = $privateKey->getPublicKey()->toString("XML"); // export public XML key
print($xmlFormattedKey);
Topaco
  • 40,594
  • 4
  • 35
  • 62