Now that you know that SSH keys are about authentication and not session encryption, and that they let you disable password logins on your server, you may be excited about getting to work using SSH keys with your server.1 There are just two things that can stop you:
- You have no SSH keys.
- Your server doesn’t know your (as of yet non-existent) public key.
Fortunately, we can solve both of these problems without too much suffering. Today we’ll solve problem one and generate ourselves some SSH keys.
As always, I am writing from the perspective of a person using a Mac or iOS device, and working on Linux servers. If you are running Windows or Linux on your local computer, you’ll have to google elsewhere. Today I’m just going to show how to generate keys on the Mac. Later sometime I’ll show you some iOS and iPadOS apps that can generate or transfer keys for you.
In Unix-land, ssh keys are generated using the surprisingly named ssh-keygen utility. The ssh-keygen command, like almost every other interesting Unix command, has lots of options, but we’ll keep it simple for our purposes.
We’re only going to concern ourselves with two ssh-keygen options: -t (type of key to generate) and -f (the filename to save the key to).
About that -t option… there are several different types of SSH keys you can generate, and some of them also have their own subset of decisions to make about how many bits they should be.
Currently, there are only really three types of keys to consider:
To simplify a billion words of reading and research into one line, use ed25519 whenever possible.
I still encounter some iOS/iPadOS apps that haven’t been updated to handle ed25519 yet (I’m looking at you, Screens and Code Editor), so I have been using ECDSA with a bit length of 521 in those cases. However, there actually is some concern about whether or not ECDSA was compromised by NIST for the NSA, so maybe I should be using RSA for those apps that I can’t use ed25519 in.
At any rate, on the Mac we can use ed25519, so that’s what we’re going to do. With ed255219, we don’t need to specify a bit length.
SSH keys are valuable and need to be kept secret. They are (literally) your key to any servers that have been given a copy of the public key half of your SSH key. Proper permissions need to be set on your ssh keys and the directory they are in, or else they will be ignored by ssh when trying to use them to establish a connection.
Your SSH keys on your Mac should be put inside your home directory in a sub-directory named .ssh. The . at the front of the directory name indicates that it’s a hidden directory – it won’t show up in the Finder or in a terminal ls listing. To see it, you need to perform the ls command with the -a option.
Open terminal, and make sure you’re in your home directory. Type ls -a and see if you have a .ssh directory already. If you’re reading this, most likely you do not.
If you don’t have a .ssh directory, create one with the following:
testdummy@dragonfly:~$ mkdir .ssh testdummy@dragonfly:~$ chmod 700 .ssh
Now your .ssh directory should show up with the correct permissions:
testdummy@dragonfly:~$ ls -la total 24 drwxr-xr-x 3 testdummy testdummy 4096 Dec 19 23:55 ./ drwxr-xr-x 7 root root 4096 Dec 19 23:53 ../ -rw-r--r-- 1 testdummy testdummy 220 Dec 19 23:53 .bash_logout -rw-r--r-- 1 testdummy testdummy 3771 Dec 19 23:53 .bashrc -rw-r--r-- 1 testdummy testdummy 807 Dec 19 23:53 .profile drwx------ 2 testdummy testdummy 4096 Dec 19 23:55 .ssh/ testdummy@dragonfly:~$
Change directory to .ssh, and let’s get ready to make some keys!
testdummy@dragonfly:~$ cd .ssh testdummy@dragonfly:~/.ssh$
Ok. I promised you I was going to keep our use of ssh-keygen simple, and I will keep that promise. After a drumroll of your choosing, please perform the following command:
testdummy@dragonfly:~/.ssh$ ssh-keygen -f supermegakey3000 -t ed25519
Immediately you’ll notice something I did NOT tell you about SSH keys: they can be protected with passphrases.
Generating public/private ed25519 key pair. Enter passphrase (empty for no passphrase):
For now, just hit return. The key you’re generating is just for testing purposes, and we can talk about passphrases another day. You’ll have to hit return twice to get past the passphrase phase of ssh-keygen.
After that, you’ll see something similar to this:
Your identification has been saved in supermegakey3000 Your public key has been saved in supermegakey3000.pub The key fingerprint is: SHA256:4TZO9TP6E52SrwL9IKc11aAnF0Vd4tLUTvbCVD3QO9A testdummy@dragonfly The key's randomart image is: +--[ED25519 256]--+ | +O+=| | o=.E*| | . ...*+++| | . oo.+.+oo| | S. =+o o.| | +o.*.+oo | | .*.+ + | | . ..o . | | .oo | +----[SHA256]-----+ testdummy@dragonfly:~/.ssh$
Congratulations, you’ve created an SSH key pair consisting of a public key and a private key, which you can see with a good old-fashioned ls -l command.
testdummy@dragonfly:~/.ssh$ ls -l total 8 -rw------- 1 testdummy testdummy 411 Dec 20 00:00 supermegakey3000 -rw-r--r-- 1 testdummy testdummy 101 Dec 20 00:00 supermegakey3000.pub testdummy@dragonfly:~/.ssh$
If you noticed the .pub extension on the second key and wondered if that is the public key, and therefore the other file must be the private key, congratulations! You’re very perceptive. And you’re correct.
You’ll also notice the permissions are different on the public and private keys. The public key permissions are set to 644 (read and write for owner, read for group, and read for everyone) and 600 for the private key (read and write for owner, and no permissions for anyone else). These are the correct permissions generated by ssh-keygen.
SSH keys are just text files. As such, anyone can see what’s in them, which is why we made sure our file permissions were correct on them, and why when we are creating keys that we’re really going to use, we’ll set a passphrase on them. But for now, let’s look at each key file.
First up, our public key:
testdummy@dragonfly:~/.ssh$ more supermegakey3000.pub ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDT1WEEa2AU3JVDRGsWp2J4wqi2ijWzc/AGNnoyqKywy testdummy@dragonfly testdummy@dragonfly:~/.ssh$
The .pub file contains first a statement about the key type, followed by the public key, then the name of the user account that generated the key and the host name of the computer they generated it on.
That part at the end with the username and host name are just for user convenience so that, if you have multiple keys on a server that you’ll accept for login purposes, you can tell which key goes with what device or computer. You don’t need that in the .pub key file for it to function, or you can change it to whatever you like.
If you’re pretty unimpressed with the looks of the public key, remember what I said about ed25519 using shorter keys than comparably strong SSH keys of differing formats.
And here’s our private key:
testdummy@dragonfly:~/.ssh$ more supermegakey3000 -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACA09VhBGtgFNyVQ0RrFqdieMKotoo1s3PwBjZ6MqissMgAAAJj2YNoG9mDa BgAAAAtzc2gtZWQyNTUxOQAAACA09VhBGtgFNyVQ0RrFqdieMKotoo1s3PwBjZ6MqissMg AAAEDr+QYUC6LymdiHLtfmLC6LyRaPR9LJHBy1Akx8swiFeTT1WEEa2AU3JVDRGsWp2J4w qi2ijWzc/AGNnoyqKywyAAAAE3Rlc3RkdW1teUBkcmFnb25mbHkBAg== -----END OPENSSH PRIVATE KEY----- testdummy@dragonfly:~/.ssh$
Woohoo! That’s more like it! Unfortunately, no one ever gets to see this except you, unless things have gone horribly awry. If, for example, you post this on the internet in a blog post, you should probably never use that key for anything. It’s considered compromised.
That’s literally all there is to SSH key generation: firing up the ssh-keygen command and specifying the file name and key type desired.
testdummy@dragonfly:~/.ssh$ ssh-keygen -f supermegakey3000 -t ed25519 Generating public/private ed25519 key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in supermegakey3000 Your public key has been saved in supermegakey3000.pub The key fingerprint is: SHA256:amXi9gqrCBJXQiBJzuc0WF6H6dmFHasPpYw+ghWYHsU testdummy@dragonfly The key's randomart image is: +--[ED25519 256]--+ |++oo .o.o.. | |=.BE.o.. o. | | B.*o o .o | |. =oooo.+ | |...o ..=S | | oo .. =o | |o. ..o= . | |o. .=.. | |. ... ... | +----[SHA256]-----+ testdummy@dragonfly:~/.ssh$
If you remember from our discussion of basic SSH key theory, any computer you’d like to connect to using your SSH key must know what your public key is. It needs to know it so that it can use it to encrypt a message to you as an authentication challenge. Next time we’ll talk about getting the public key onto a remote server so we can actually use it.
By the way, I told you posting your private key on the internet was a bad idea, so if you do (as I did), delete this SSH key pair and start over.
testdummy@dragonfly:~/.ssh$ ll total 16 drwx------ 2 testdummy testdummy 4096 Dec 20 00:16 ./ drwxr-xr-x 3 testdummy testdummy 4096 Dec 20 00:03 ../ -rw------- 1 testdummy testdummy 411 Dec 20 00:16 supermegakey3000 -rw-r--r-- 1 testdummy testdummy 101 Dec 20 00:16 supermegakey3000.pub testdummy@dragonfly:~/.ssh$ rm super* testdummy@dragonfly:~/.ssh$
If you read this in your head as “remove superstar”, you win an invisible honorary silly award.
Unless your name is Vic Hudson, in which case you think passwords are just fine. ↩︎