2

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?

Jim
  • 195
  • 1
    The issue is that ssh-keygen generates an SSH key, while openssl rsa doesn't read SSH keys - it can read PKCS#1 or PKCS#8. – garethTheRed Oct 01 '21 at 20:33
  • @garethTheRed: But isn't that a PEM format? And if not with openssl then how can I do the exact equivalent with another tool? – Jim Oct 01 '21 at 20:43
  • @garethTheRed: if possible, please can you check the updated post? – Jim Oct 01 '21 at 21:56
  • @Jim - What you generated was an OpenSSH private key but you were attempting to import a RSA private key. Looking closer at the original error, it was indicating the problem was related to the cryptographic cipher being used. – Ramhound Oct 01 '21 at 22:11
  • 1
    Effectively dupe https://superuser.com/questions/1616369/why-is-ssh-keygen-generating-two-types-of-keys- and https://superuser.com/questions/1470852/differences-between-ssh-keygen-private-keys-and-libressls – dave_thompson_085 Oct 02 '21 at 00:39

2 Answers2

5

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.
u1686_grawity
  • 452,512
  • For the last option - if I do an in-place conversion of an existing SSH key, is it still usable as SSH key for login? – Peregrino69 Oct 02 '21 at 01:44
  • @Peregrino69: Yes, PKCS#1 (PEM) used to be OpenSSH's default format for private keys (it's probably why OP expected the ssh-keygen output to be PEM), and because it just offloads the reading/writing to OpenSSL it has also supported PKCS#8 for a long time. – u1686_grawity Oct 02 '21 at 07:08
0

I had to struggle with this subject on OSX (Ventura)

  • permissions (bad permissions, Could not read... )
  • wrong format (PEM/PKCS8 vs "SSH-type")

i came with this solution

# generate a PRIVATE KEY
openssl genpkey -algorithm RSA -aes-256-cbc -outform PEM -out private_key.pem -pkeyopt rsa_keygen_bits:2048
# create a passphrase made of 4 chars minimum

SUDO ! change permissions to 600 at most

sudo chmod 600 private_key.pem

but 400 should work and is event more secure

sudo chmod 400 private_key.pem

SUDO again

extract THE PUBLIC KEY in PKCS8 file format

sudo ssh-keygen -e -f private_key.pem -m PKCS8 > public_key.pem

enter your passphrase

give the public key to someone who wants to protect the data.in.txt file. She or he will do the following to encrypt it:

# SUDO again
sudo openssl pkeyutl -encrypt -pubin -inkey public_key.pem -in data.in.txt -out data.enc.txt

You receive the encrypted file (data.enc.txt) to be decrypted:

# SUDO again
sudo openssl pkeyutl -decrypt -inkey private_key.pem -in data.enc.txt -out data.out.txt

then you can read the confidential information

cat data.out.txt

you can do the same method so he/she extract his/her public key in order to encrypt your public key to protect it before sending it.