Richard Reiber Richard Reiber - 7 months ago 130
PHP Question

Generate RSA private SSH key (OpenSSL)

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);


Then,
$pem
is this:

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


There is no authentication possible with this key in PHP. The OpenSSH client is working (on Mac). I just have to convert it:

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 RSA PRIVATE KEY, not just a PRIVATE KEY. How can I create this with PHP and OpenSSL PHP implementation?

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"];
?>