4

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?

jww
  • 97,681
  • 90
  • 411
  • 885
Richard
  • 2,840
  • 3
  • 25
  • 37
  • You know that these are called *private* keys for a reason, right? You're gonna want to throw this one away. – Sammitch Apr 18 '16 at 21:39
  • @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 Apr 18 '16 at 21:42
  • 3
    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 Apr 18 '16 at 22:07
  • 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 Apr 18 '16 at 22:12
  • @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 Apr 18 '16 at 22:17
  • @RichardReiber I've just updated mine to 1.0.2g, no change for me – scrowler Apr 18 '16 at 22:19
  • @RobbieAverill: Same here. I have "OpenSSL 0.9.8zh" on PHP 5.6 working on my local machine. – Richard Apr 18 '16 at 22:21

1 Answers1

6

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"];
?>
Community
  • 1
  • 1
miken32
  • 42,008
  • 16
  • 111
  • 154
  • I saw this already and was afraid of "PHP 4". I have just checked the Github repository and it is not as outdated as I thought before. I will try it if i cannot find another solution with another OpenSSL version. – Richard Apr 18 '16 at 22:22
  • 1
    Yes, I'll update the link as I think the Sourceforge one is not current! – miken32 Apr 18 '16 at 22:27