Php – Generate RSA private SSH key in PHP

opensslPHPprivate-keyrsassh

I have generated a SSH key with PHP OpenSSL:

$rsaKey = openssl_pkey_new(array( 
    'private_key_bits' => 4096,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
));
$privKey = openssl_pkey_get_private($rsaKey); 
openssl_pkey_export($privKey, $pem);

This results in $pem looking like this:

-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQC8ggt6rVHYnqNP
...
e95+EXbPc6THyWt9pgwOsJltpylIYG4=
-----END PRIVATE KEY-----

But I cannot authenticate using this key. Before I can use it, I have to convert it using this command:

openssl rsa -in xxx.key -outform pem > xxx.key2

The result of the conversion is this:

-----BEGIN RSA PRIVATE KEY-----
MIIJKQIBAAKCAgEAvIILeq1R2J6jT+xjlK5NrOqFZTOJ4PByvgPQNbb2Kp7c3W15
...
o1t2KBkaSoR+JyOPOZakq5BLv8lgD3vefhF2z3Okx8lrfaYMDrCZbacpSGBu
-----END RSA PRIVATE KEY-----

Both are PEM format, but the second is a RSA private key. With the second, PHP can login. So I need a key that starts with RSA PRIVATE KEY, not just PRIVATE KEY. How can I create this with PHP and OpenSSL PHP implementation?

Best Answer

So, these are two different key types. You're looking for PKCS #1, but getting PKCS #8.

This appears to be related to the version of OpenSSL that PHP uses. Versions since 1.0 create a PKCS #8 file, and there's nothing the PHP developers want to do about it. The same issue arises when doing it from the command line with this command:

openssl req -new -keyout mykey.key -out mycertreq.csr -nodes -sha1 -newkey rsa:2048

You can try using an external library called phpseclib, though I haven't tried it myself:

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

$rsa = new Crypt_RSA();
$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_OPENSSH);
$result = $rsa->createKey();
echo $result["privatekey"];
?>