Alexander
Alexander

Reputation: 2297

Convert pem rsa key to xml for C# RSACryptoServiceProvider.FromXmlString

I generating RSA public and private key with PHP:

function genKeys($pkey, $skey)
{
    $pkGenerate = openssl_pkey_new(array(
        'private_key_bits' => 2048,
        'private_key_type' => OPENSSL_KEYTYPE_RSA
    ));

    $pkGeneratePrivate = null;
    openssl_pkey_export($pkGenerate, $pkGeneratePrivate);

    $pkGenerateDetails = openssl_pkey_get_details($pkGenerate);
    $pkGeneratePublic  = $pkGenerateDetails['key'];

    openssl_pkey_free($pkGenerate);

    $pkImport        = openssl_pkey_get_private($pkGeneratePrivate);
    $pkImportDetails = openssl_pkey_get_details($pkImport);
    $pkImportPublic  = $pkImportDetails['key'];

    openssl_pkey_free($pkImport);

    $result = (bool) strcmp($pkGeneratePublic, $pkImportPublic);

    if ($result) {
        file_put_contents($pkey, $pkGeneratePrivate);
        file_put_contents($skey, $pkGeneratePublic);
    }

    return $result;

}

And I need use PEM file with RSACryptoServiceProvider.

So, how to convert PEM public and private to XML?

Upvotes: 3

Views: 4896

Answers (2)

hakre
hakre

Reputation: 197544

This answer is a little late, I had problems to understand what you're looking for exactly and could decipher it now.

.Net in RSACryptoServiceProvider.FromXmlString uses an XML key format similar to the one from XKMS 2.0 just with a different document element.

The openssl extension in PHP doesn't offer a function to create it directly, however with the help of the openssl_pkey_get_details() function you can obtain all details of the RSA key you need to create the XML file. Then it's pretty straight forward:

$rsa = openssl_pkey_get_details($pkGenerate)['rsa'];

$xml = new SimpleXMLElement("<RSAKeyValue/>"); // Use <RSAKeyPair/> for XKMS 2.0

// .Net / XKMS openssl RSA indecies to XML element names mappings
$map = ["n"    => "Modulus", "e"    => "Exponent", "p"    => "P",        "q"    => "Q",
        "dmp1" => "DP",      "dmq1" => "DQ",       "iqmp" => "InverseQ", "d"    => "D",];

foreach ($map as $key => $element) {
    $xml->addChild($element, base64_encode($rsa[$key]));
}

$xml->asXML('php://output');

This example continues after your key generation which you have the resource in the $pkGenerate variable and the "stores" it to stdout (for demonstration purposes). You can also store it to file:

$xml->asXML('/path/to/file');

or assing it to a variable:

$xmlString = $xml->asXML();

So technically if you're using the openssl extension, you don't need to add full phpseclib just to create the XML.

Related material:

Upvotes: 3

halifatfree
halifatfree

Reputation: 46

Using http://phpseclib.sourceforge.net/ :

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

$rsa = new Crypt_RSA();
$rsa->loadKey('...');

echo $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_XML);

Upvotes: 3

Related Questions