phpopensslrsapem

Convert RSA public key exponent and modulus to PEM formatted string


I have two binary buffers containing the modulus and exponent of a public RSA key in PHP (both in big-endian). I need to convert these two values to a PEM formatted string so that it can be used to encrypt data with the openssl extension, for example with openssl_public_encrypt.

When researching this topic, I only found solutions using phpseclib, which I cannot use in this scenario. How can I convert the values manually (as I think openssl doesn't offer such functionality)?


Solution

  • Besides the manual generation of a PEM encoded key in X.509/SPKI format mentioned in the comment, it is also possible to import the modulus and public exponent with openssl_pkey_new(), e.g. as follows:

    <?php
    $n = hex2bin("c22a3e485cc5bca290f6f97972d6984a2d3da3c937521eebe87b76789bfe852699e80eb14d75480554a6d0abcfc5a265a6360f4c2725dac744c97943d9487592150a53bafd38ddeba4df2914701eadee6283f2465444a1c66b7913f8f33329989d27e4a125b8e2e95ebd0794c0ffcc882e550b52898d37c3ef78215f4b50d3efd18d3249d9c2f2142e1514d6e804c0958a852bcfc200ddcd0a20e979d3baacc10bccb21daf0533030d225f8a9a4018bcd48965f152589dfafc8e0bc182b5a83ad6d692a2bc42c35e22ae4fadb21ee15a30c39124c59f680284f31f5d78f5d3f942bf4506dbd4d5515080b1acb8a6ccf3826738cf08604aca9045df77f4125ec7");
    $e = hex2bin("010001");
    
    $key = openssl_pkey_new([
        'rsa' => [
            'n' => $n,
            'e' => $e,
            'd' => '',
            'p' => '',
            'q' => '',
            'dmp1' => '',
            'dmq1' => '',
            'iqmp' => ''
        ]
    ]);
    
    $public_key_pem = openssl_pkey_get_details($key)['key'];
    echo $public_key_pem, PHP_EOL;
    ?>
    

    This provides a PEM encoded key in X.509/SPKI format.

    Note that this approach, or more precisely the $options parameters used, is not documented (s. openssl_pkey_new()), so there is no guarantee that this will work in future versions.
    In my tests, it works for versions 5.4.0 up to the current version 8.3.10.