4
votes

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?

1
You know that these are called private keys for a reason, right? You're gonna want to throw this one away.Sammitch
@Sammitch: Of course. But there is no reason why to hide them. They are generated on a non-productive environment and not used by any system.Richard
This appears to be version dependent. Running it on PHP 5.5.31, I get BEGIN RSA PRIVATE KEY but running it on PHP 7.0.4 I get BEGIN PRIVATE KEY. Could be related to OpenSSL version it was compiled with as well.miken32
This is a great question. In regards to @miken32's comment just now, I'm running PHP 5.5.30 via CLI and I get "private key". Running openssl rsa -in myKey.pem -check says "RSA key ok" then proceeds to convert it to what you're expecting to see. The documentation is misleading as it suggests that what you're doing should result in an RSA key (visibly obvious via the comments at either end)scrowler
@miken32: Thank you. I can reproduce this on my local machine. I just have installed PHP 7 on our test environment. That is not the problem. The problem seems to be the OpenSSL version. Currently, it is OpenSSL 1.0.1k. I try to update it.Richard

1 Answers

6
votes

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