OpenSSH – Fix ‘Unable to Load Private Key’ for Valid PEM

macopensshopensslrsassh-keys

I have created a public/private key pair with this command:

ssh-keygen -t rsa -b 4096 -f my-trusted-key -C "Just a public/private key"  

I can open the private key file and I see:

$ cat my-trusted-key
—–BEGIN OPENSSH PRIVATE KEY—– b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
etc

but when I run the following command:

$ openssl rsa -in my-trusted-key -text -inform PEM -noout

I get the following error

unable to load Private Key 4506685036:error:09FFF06C:PEM
routines:CRYPTO_internal:no start
line:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/crypto/pem/pem_lib.c:684:Expecting:
ANY PRIVATE KEY

what is the issue here and it fails?

Update
After the comment from @garethTheRed I created a private key using openssl as follows:

$ openssl genrsa -out anotherkey.key 2048  

and I can see:

$ cat anotherkey.key
—–BEGIN RSA PRIVATE KEY—– MIIEogIBAAKCAQEAuc3m0tXo8UQvF8CJi9Cy7580WxfKvFHYZ3F06Uh19s9c51R/

and now the command works i.e.

openssl rsa -in anotherkey.key -text -inform PEM -noout

Private-Key: (2048 bit) modulus:
00:b9:cd:e6:d2:d5:e8:f1:44:2f:17:c0:89:8b:d0:
b2:ef:9f:34:5b:17:ca:bc:51:d8:67:71:74:e9:48

but I don't understand the difference. Both files are PEM format, both when viewed using cat show the same format.
So why the pem generated by ssh-keygen is rejected?

Best Answer

isn't that a PEM format?

No, it's just a "PEM-like" format. There's a "-----HEADER-----" and there's Base64-encoded data. But that's where the similarities end – the actual data structure found within that Base64 blob is completely different than that of PEM; it isn't even using ASN.1 DER like typical "PEM" files do, but uses the SSH data format instead.

The ssh-keygen command used to output RSA private keys in the OpenSSL-style PEM or "bare RSA" or PKCS#1 format, but that's no longer the default. You can still get it using the -m PEM option, and you can also get the PKCS#8 format using -m PKCS8. Both are OpenSSL-compatible (PKCS#8 is preferred nowadays.)

Quick summary:

  • BEGIN RSA PRIVATE KEY: known as "PEM" or "PKCS#1", contains ASN.1 DER-formatted data
  • BEGIN PRIVATE KEY: "PKCS#8", more versatile than PEM (can hold any algorithm), but still counts as "PEM" for most purposes (most tools will recognize both formats), contains ASN.1 DER-formatted data
  • BEGIN ENCRYPTED PRIVATE KEY: still PKCS#8 but password-encrypted
  • BEGIN OPENSSH PRIVATE KEY: not "PEM", contains SSH2-formatted data specific to OpenSSH
  • Use openssl genpkey to create PKCS#8 format keys, openssl genrsa to create PKCS#1 format keys, openssl pkey to convert PKCS#1 to PKCS#8.
  • Use ssh-keygen -p -m PEM (password change with the -m option) to do an in-place conversion of other SSH key types to PKCS#1 (PEM). Similarly, use ssh-keygen -p -m PKCS8 to do in-place conversion to PKCS#8. If you do a password change without specifying -m, the key will get converted to the OpenSSH format instead.
Related Question