For an ordinary user, how would I verify that a private key file was generated using reasonably secure algorithms? In response to things like allegedly insecure ssh-keygen defaults.

  • On *nix systems, grep BEGIN ~/.ssh/id_* ... If it doesn't have OPENSSH PRIVATE KEY ... then you have the old format keys. .... I typically use my PGP keys through ssh-agent and let GPG handle the key management. – RubberStamp Jan 7 '19 at 3:05
  • @RubberStamp Assuming that an ordinary user has no idea what "old format" means, how would they know what that means and whether it's secure or not? – l0b0 Jan 7 '19 at 3:06
  • Related... and possible dup ... try openssl asn1parse -in - ... – RubberStamp Jan 7 '19 at 3:24
  • @RubberStamp @TomLeek is able to read that output, but I'm not. The man page just says "Some knowledge of the ASN.1 structure is needed to interpret the output." I wouldn't know where to begin to establish within a reasonable amount of time what the KDF is, for example. – l0b0 Jan 7 '19 at 4:21
  • @RubberStamp+ asn1parse doesn't work at all on either kind of encrypted privatekey file ssh-keygen can create, neither the OpenSSL 'traditional' format with PEM-level encryption nor the OpenSSH 'new' format with body-level encryption but non-ASN.1 encoding (instead XDR-like) – dave_thompson_085 Jan 7 '19 at 5:05

As RubberStamp points out, this is covered in detail in stronger encryption for SSH keys but to summarize:

Look at the words in the first line, and the next one or two.

 Proc-Type: 4,ENCRYPTED
 DEK-Info: DES-EDE3-CBC,(hex)

 (several lines of base64)

(or similarly with DSA PRIVATE KEY or EC PRIVATE KEY) is the old, bad-PBKDF format.

 (base64 immediately)
 -----END RSA PRIVATE KEY----- # ditto 

is the old unencrypted format, which is even worse.

 (several lines of base64)

is the OpenSSH-specific 'new' format, which is why it says OPENSSH right there. However, this format doesn't directly show whether it's encrypted or not. The easiest way is to try reading it (either for an ssh connection, or with ssh-keygen to convert or modify it) and see if it needs a password. Alternatively, you can strip the labels and decode the base64 (conveniently, openssl base64 -d does both of these!) and look at it:

$ openssl base64 -d <se200935.clr |od -c
0000000   o   p   e   n   s   s   h   -   k   e   y   -   v   1  \0  \0
0000020  \0  \0 004   n   o   n   e  \0  \0  \0 004   n   o   n   e  [snip rest]

$ openssl base64 -d <se200935.enc |od -c
0000000   o   p   e   n   s   s   h   -   k   e   y   -   v   1  \0  \0
0000020  \0  \0  \n   a   e   s   2   5   6   -   c   b   c  \0  \0  \0
0000040 006   b   c   r   y   p   t [snip rest]
  • So is the "new OpenSSH-specific format" considered secure or not? I don't get this from your answer unfortunately. – bers Nov 26 '19 at 10:09
  • 1
    @bers: Yes, OpenSSH 'new' format -- IF encrypted (see edit) -- uses bcrypt with sane parameters, which is a good PBKDF. It also uses good symmetric encryption, but that's not a differentiator, even OpenSSH 'old' format which is OpenSSL 'traditional' format does that. – dave_thompson_085 Nov 28 '19 at 8:09
  • This hex dumping answer is great. A small simplification that's easier on the eyes is to use strings instead. E.g. openssl base64 -d < ~/.ssh/id_rsa | strings – JPvRiel Jan 11 at 18:29
  • hexdump -C is a very readable alternative. – Marcus Apr 21 at 7:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.