Most users would simply type ssh-keygen and accept what they're given by default.

But what are the best practices for generating ssh keys with ssh-keygen?

For example:

  • Use -o for the OpenSSH key format rather than the older PEM format (OpenSSH 6.5 introduced this feature almost 3 years ago on 2014-01-30)

  • How should one calculate how many rounds of KDF to use with -a?

  • Should -T be used to test the candidate primes for safety? What -a value to use with this?

  • For the different key types, what are the recommended minimum -b bit sizes?

  • etc... (there are a mind-boggling set of options in the manual page).

  • (2) crypto.stackexchange.com/questions/40311/… (3) -T tests probable-primeness not 'safety'; you should never install a moduli file that isn't primes (4) for RSA at least 2048 maybe 3072; for DSA NIST requires group 2048 but also subgroup and hash 224+ and SSH can't handle the latter (yet?); for ECDSA the minimum possible 256 is fine; for Ed25519 there is no choice – dave_thompson_085 Nov 24 '16 at 6:18
  • Confusingly the manual explanation for -T is: Test DH group exchange candidate primes (generated using the -G option) for safety.. What is primes(4), and how does one translate this into something that can be typed at a command line (eg, in the RSA case)? – Tom Hale Nov 24 '16 at 7:26
  • 'primes' is the last word of my '(3)' about your third bullet and '(4)' is about your fourth bullet. Yes the man page for ssh-keygen is misleading; the page it links to for moduli(5) (that '(5)' meaning section 5 in the Unix man scheme) is better but still not exact. In short if you want to generate 'moduli' (really pairs of modulus and generator) always do -G THEN -T and use only the second result. It does produce 'safe' primes (p=2q+1) but 'safe' here is a historical relic, it is nonsmooth prime that matters. – dave_thompson_085 Nov 24 '16 at 9:13
  • Bleah! Of course no prime is smooth, and I meant DH wants prime with order of Zp* i.e. p-1 nonsmooth. While I'm at it, most of the mind-boggling options are about key import/export/conversion and file management and OpenSSH's idiosyncratic certs; the actual key (and even parameter) generation options in the program named keygen are relatively few. – dave_thompson_085 Nov 26 '16 at 7:55
up vote 75 down vote accepted

I recommend the Secure Secure Shell article, which suggests:

ssh-keygen -t ed25519 -a 100

Ed25519 is an EdDSA scheme with very small (fixed size) keys, introduced in OpenSSH 6.5. These have complexity akin to RSA at 4096 bits thanks to elliptic curve cryptography (ECC). The -a 100 option specifies 100 rounds of key derivations, making your key's password harder to brute-force.

However, Ed25519 is a rather new key algorithm with incomplete adoption, so it may not be available on all servers. For those, generate a 4096 bit RSA key:

ssh-keygen -t rsa -b 4096 -o -a 100

(A note on the -o option, since it is now missing(!) from the ssh-keygen man page: This dictates usage of the new OpenSSH format to store the key rather than the previous default, PEM. Ed25519 already requires this, so we don't need to explicitly state it given -t ed25519. -o requires OpenSSH client v6.5+, so you may have to skip it, but it's better to keep for its “increased resistance to brute-force password cracking” (as noted by past man pages). See this answer for more detail.)

Do not consider the other new ECC algorithm called ECDSA. It is considered suspect (it has known weaknesses and since the US government has been involved in its development, it may be compromised beyond that). Ed25519 was developed without any known government involvement.

Stay well away from DSA (“ssh-dss”) keys: they're not just suspect, DSA is insecure.

  • 3
    Thank you, just what I was looking for - practical command line examples. – Tom Hale Dec 1 '16 at 1:30
  • 3
    The first -o is not needed as the man page says Ed25519 keys always use the new private key format. – Tom Hale Dec 10 '16 at 4:33
  • good point. removed. – Adam Katz Dec 14 '16 at 18:56
  • 2
    @juanmah – Yes, that's why I linked the Ed25519 adoption page and offered RSA 4096 as an alternative. That page points to Cyberduck for implementing Ed25519 on Azure (though that's presumably for Windows, not Linux). I'd assume you could upgrade OpenSSH on the Linux VM; the newer the better, but Ed25519 requires OpenSSH 6.5+. If you want a lightweight server, consider installing pts-dropbear. – Adam Katz Mar 5 at 15:20
  • 1
    As of 7.8 about a month ago (see the first bullet) ssh-keygen writes 'new' format automatically, and if you want legacy format (for other than ed25519) you use -m PEM – dave_thompson_085 Oct 2 at 1:00

Most users would simply type ssh-keygen and accept what they're given by default.

Yes. To do a security for people, it needs to be simple. Therefore the default option should be safe, compatible and fast. You can provide alternatives, but default should be "good enough" for these who don't care. Therefore RSA (2048) in the old PEM format is the default at the moment.

  • Use -o for the OpenSSH key format rather than the older PEM format (OpenSSH 6.5 introduced this feature almost 3 years ago on 2014-01-30)

Three years is nothing. A lot of containers managed to evolve during these years, but SSH is here more than 20 years and still needs to deal with older clients. The new OpenSSH format is not widely adopted and supported yet.

  • How should one calculate how many rounds of KDF to use with -a?

Depends on the use case. Creating your key for your "stuff" repo on Github will be different than creating a keys in your favorite national agency as a certification authority or to access super-secret documents on dedicated server.

As pointed out, this is only for the new format, which is not yet widely used and it increases the time to decrypt key. The default number of rounds is 16 (would be nice to see it documented somewhere). More in the Cryptography question.

  • Should -T be used to test the candidate primes for safety? What -a value to use with this?

No. It is used for generating primes (/etc/ssh/moduli) for DH key exchange. It is not used in any way for generating SSH keys. How to generate and test the moduli file is explained in separate chapter MODULI GENERATION of manual page for ssh-keygen.

  • For the different key types, what are the recommended minimum -b bit sizes?

This is not SSH specific, but generally key sizes are recommended by NIST in this document, page 12 (per 2015):

RSA (2048 bits)
ECDSA (Curve P-256)

The Ed25519 does have fixed size so the -b parameter is ignored.

  • 3
    It is usually best practice to generate a key on the same system where you use it, so incompatibility between new file format and old software isn't a big problem. The algorithm (-t) is more often an issue: ed25519 keys won't interop with older versions, even ECDSA won't work with very old or RedHat-formerly-nobbled versions, while new versions reject DSA unless you tweak the configuration (there are already several Qs on that) -- so as you said we end up with RSA as the the works-everywhere choice. – dave_thompson_085 Nov 26 '16 at 8:02
  • 1
    Regarding protocols, my sshd_config man page says: The default is ‘2’. Protocol 1 suffers from a number of cryptographic weaknesses and should not be used. It is only offered to support legacy devices. – Tom Hale Dec 7 '16 at 23:25
  • Yes. I don't even think somebody would want to allow this protocol. It is not default on any of the current systems and there is no reason to allow it. – Jakuje Dec 8 '16 at 7:34

Here's a one liner for Ed25519 based on recommended values: (without passphrase)

ssh-keygen -t ed25519 -a 100 -f ~/.ssh/id_ed25519 -q -N ""

Another one for RSA:

ssh-keygen -t rsa -b 4096 -o -a 100 -f ~/.ssh/id_rsa -q -N ""
  • -N: New passphrase
  • -q: Silence ssh-keygen
  • 5
    An empty passphrase is not a best practice. Yes, it is necessary for certain automated tasks, but those are exceptions. Your filenames are the defaults, making the use of -f output_keyfile unnecessary. – Adam Katz Apr 11 at 18:34

For extra protection use chattr on those keys e.g. sudo chattr + /home/"username"/.ssh/id_rsa.pub (Also on /etc/passwd as well as /etc/shadow etc)

  • 1
    How does this "extra protection" work? Why do you suggest doing it for the public key rather than the private key? More explanation is necessary, especially since the man page seems to suggest that your example command essentially does nothing at all. – AndrolGenhald Nov 29 at 21:05
  • Chattr prevents file alteration - in the case of any ssh keys it keeps someone from simply changing them. Not sure if chattr is mentioned in the man pages but it makes files immutable. – user192494 Nov 30 at 18:13
  • In that case you probably meant chattr +i /home/... rather than chattr + /home/.... I fail to see how this is a good idea though, you are prevented from changing or removing the keys without root access, but what does that gain you besides frustration when you need to change keys? – AndrolGenhald Nov 30 at 18:23

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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