How convert RSA public key, from XML to PEM (PHP)?
There is no standard for storing RSA public keys in XML. So the manner of conversion will depend on the XML you have.
Maybe you should have a look here:
Extract the two base64-encoded strings, convert and pass to PEAR::Crypt_RSA, then export as text file, then openssl convert?
we know
.pem - (Privacy Enhanced Mail) Base64 encoded DER certificate, enclosed between "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"
The SignatureValue element contains the Base64 encoded signature result - the signature generated with the parameters specified in the SignatureMethod element - of the SignedInfo element after applying the algorithm specified by the CanonicalizationMethod.
so we end up with
$xml = simplexml_load_file($xmlFile); // or simplexml_load_string
$pem = "-----BEGIN CERTIFICATE-----\n";
$pem .= $xml->SignatureValue;
$pem .= "\n-----END CERTIFICATE-----";
// save to file
if your xml-file isn't a XML_Signature
$xml = simplexml_load_file($xmlFile); // or simplexml_load_string
$pem = "-----BEGIN CERTIFICATE-----\n";
$pem .= $xml->nodeWithWantedValue; // use base64_encode if needed
$pem .= "\n-----END CERTIFICATE-----";
I'm assuming that by XML format, you mean XML DSig RSAKeyValue, and that by PEM format you mean what OpenSSL exports in between -----BEGIN PUBLIC KEY-----
and -----END PUBLIC KEY-----
.
You need first to extract the modulus and public exponent from the XML.
<RSAKeyValue>
<Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W
jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV
5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=
</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
You can easily convert these into a bit string using base64_decode
.
Once this is done, you need to build the ASN.1 public key structure somehow.
What OpenSSL exports between BEGIN/END PUBLIC KEY is an X.509 SubjectPublicKeyInfo structure.
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
The subjectPublicKey
is made of a sequnce is described in the PKCS#1 spec:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER,
publicExponent INTEGER
}
The algorithm
(an AlgorithmIdentifier
) is also described in the PKCS#1 spec (see section A.1):
rsaEncryption
OBJECT IDENTIFIER ::= { pkcs-1 1 }
This structure needs to be serialized in DER form, then base64-encoded and then placed between the BEGIN/END delimiters.
I don't know of any PHP library to do the ASN.1/DER encoding unfortunately (the rest is relatively easy, but dealing with ASN.1 tends to be tedious).
The PHP/PEAR Crypt_RSA module can construct RSA public keys from modulus and exponent, but its toString()
method uses a custom format (just the base64-encoding of the result of PHP serialize
on the array structure, which has nothing to do with the ASN.1/DER encoding).
Here's an example of how to read XML RSA keys in PHP:
http://www.frostjedi.com/phpbb/viewtopic.php?f=46&t=18085