As a developer, the chances are pretty high that you have your own SSH keys to connect to servers, and be it only the server hosting the git repository. At least I haven’t heard of anybody typing his username and password into the terminal while pushing the latest commits to the remote repository. Those keys are mostly generated by using the RSA algorithm, which was and still is the standard for generating the cryptographic keys.
If you are not interested in the why and just want to get the tutorial, jump directly to the third headline.
Why RSA might not serve you well for the next decades
Invented back in 1977, RSA seemed to be the best solution to generate secure keys. Computers were slow, and it might take several decades until RSA would be rendered insecure by cracking the algorithm. However, advancing 40 years, keys are no longer really secure if they are less than 1024 bit long. Since 2013 the ENISA (European Union Agency for Cybersecurity) recommends the usage of keys with a length of 2048 bit for short-term security only. Therefore, do not generate new keys shorter than 4096 bit characters! 1
One could argument, that simply using longer key lengths would solve this problem, so let’s generate new keys with a length of 8192 bit. The problem here is, that the time to actually process keys of this length is not suitable for low-powered devices, while the actual gained security strength does not raise proportionally: A key length of 1024 bit for an asymmetrical key (which we use for SSH) only has a “real” strength of 80 bit based on symmetrical methods. Increasing that length from 1024 to 2048, however, does not increase the “real” security to 160, but only 112 bit. 2
Stage enter: Elliptic Curve Algorithms
To solve the problem that long keys lead to much higher processing times while only increasing security a bit, some really smart people figured out algorithms based on elliptic curves. Sadly, I cannot explain how those mathematical constructs work in detail. Based on the information available, those elliptic curves can be used to generate strong secure keys while keeping them actually shorter than regular RSA keys. For example, a key with a length of 256 bit is equal to an AES security of 128 bit which equals a key length of 3072 bit. This way shorter keys, while granting a stronger security than RSA, are also easier to process on low-powered machines.
Elliptic curves cryptography ist just the theory, which EdDSA (Edwards-curve Digital Signature Algorithm) and ECDH (Elliptic-curve Diffie–Hellman) are based on. While EdDSA is the cryptographic scheme, ED25519 is the actual implementation for generating SSH keys. Therefore, ED25519 is used to generate the keys and ECDH as the key exchange protocol.
There is another key generation algorithm called ECDSA that was crated to replace RSA. Unfortunately, the implementation is not considered secure, so you should definitely use ED25519 keys instead.
Given all those aspects, switching from RSA to ED25519 is a good idea. And if you know that your RSA-based key is just 1024 bit long, please switch as soon as possible!
How to switch from RSA to ED25519
Before switching, a word of caution: the following process may take some time, depending on the number of server you connect to and where your public keys are stored. Also, please do yourself a favor and make a backup of both your
id_rsa.pub files right now. Copy them to a backup directory inside your
.ssh folder, or copy them to a secure USB stick, whatever fits you most. Just keep them secure at all times.
Done? Then let’s go on.
Generate a new ED25519 key
Generating a new key based on ED25519 is the first step. The following command is an example, and you should customize it:
ssh-keygen -t ed25519 -b 521 -C "[email protected]"
-t ed25519part tells the ssh-keygen function (which is part of OpenSSL), which algorithm to use.
- Notice, that despite being located in the binary world, we do not use 512 as the key length, but 521, specified by
-b 521. Reason is the mathematical structure of the key, which does not adhere to the power of two.
- Finally, you specify your email address with the
-C "[email protected]"flag. Replace the example address with your own.
Saving the key and setting a passphrase
After hitting enter the program will ask you for the location of the newly generated key. If you have no previous ED25519 key in your .ssh folder, you may skip this because the keygen will name the new key
id_ed25519 in contrast to
id_rsa for RSA keys.
The next thing you do is specifying a passphrase. Please do not skip this. I see numerous blog posts and tutorials that are fine with skipping this step.
DO NOT SKIP SETTING A PASSPHRASE!
Setting a passphrase is the same as setting a password for your email account. If an attacker or any other random person gets access to your private key file, they can use it without any hurdles! And with access to your private key this third party has access to all servers you connect to using the key. So, please set a passphrase. In the best case it has the same strength as any other password you generate. Use a damn password manager if you don’t want to remember passwords.
After you set your passphrase, the key generator will do its magic. Congratulations, you are now the proud owner of a brand-new ED25519 key! The output should look similar to this:
Generating public/private ed25519 key pair. Enter file in which to save the key (/Users/your-name/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /Users/your-name/.ssh/id_ed25519 Your public key has been saved in /Users/your-name/.ssh/id_ed25519.pub The key fingerprint is: SHA256:FFSFtaVV9vxiPmu/DfkdS+Lqrn7+0h2jq9LtDrQRCI0 [email protected] The key's randomart image is: +--[ED25519 256]--+ | o=..+o o.o| | E.oo = o.| | .. .o o| | . . .| | S o o .| | . oo = | | .oo.Boo| | . +o++*=| | .oB*BBo+*| +----[SHA256]-----+
Pushing the new key to your servers
Of course, you want to use your new key and push it to all servers you are using. I assume that the servers you want to connect to follow the most basic security guidelines and thus are somewhat up-to-date, which means they should run the latest version of OpenSSH or a similar SSH server. If your server does not support ED25519, yet you may have some other problems right now: update the server.
An easy command to push your new SSH key to your server comes pre-installed with OpenSSH:
$ ssh-copy-id -i ~/.ssh/id_ed25519 [username]@[hostname]
Specify the used key (
-i ~/.ssh/id_ed25519) and your SSH credentials (
[username]@[hostname]), and the command should automatically copy the public key to the server. Try to log into the server using the new key to check if it’s working correctly:
ssh -i ~/.ssh/id_ed25519 [username]@[hostname]
A more manual way, of course, is to manually log into the server and past the content of the public key into the authorized key file.
PS: Don’t forget to add the new key to GitHub, Gitlab and similar services.
Configure SSH to use your new key
Last but not least: we want to tell SSH that it should use the new key by default. The main problem here is, that SSH assumes that you have an RSA key set and uses it if one was found. But we want to use our new fancy ED25519 key, and not some old RSA thingy.
The most suitable way to do this, is to use the SSH configuration file. In my opinion all other approaches are more hacks than solutions to make this work. If you don’t already use the SSH config: it’s the main configuration file for your local machine. It’s usually located at
~/.ssh/config. In that file you can specify either global settings which will then be applied to all SSH connections, or settings per host.
So, open the .ssh/config file now. At the very top, if not present already, add the following lines:
Host * IdentityFile ~/.ssh/id_ed25519
The first line tells SSH to apply the next settings to all hosts, hence the wildcard *. The second line then sets the newly generated key
~/.ssh/id_ed25519 as the new identity. That’s it. There is nothing more to configure. Make sure that, when connecting to an old server that does not yet have the new key, add the
-i ~/.ssh/id_ed25519 flag to your SSH command:
ssh ~/.ssh/id_ed25519 [username]@[some-old-server].
PS for all macOS users: to prevent macOS asking for the key passphrase every time you use the key, add
UseKeychain yes to the global settings in your SSH config. Linux users may use ssh-agent.
Despite being a pretty long blog post, you essentially have to run only a couple commands to create your new key, push it to your servers and then configure SSH to use the new key. Depending on the amount of servers you have to add the key to it may take 10-20 minutes of your time. After passing the finish line you are good to go with your new, super secure SSH key.
“Algorithms, Key Sizes and Parameters Report”, ENISA, version 1.0, October 2013 ↩︎