So you’re a programmer, or an IT fledgling, or a manager who has rolled up your sleeves to see what these “computer” things are all about anyway, and your local sysadmin or opsfolk has asked you for your “SSH key”. Maybe you’ve heard of these things before, in an intro-level cryptography class or around the internet. Maybe you’ve followed a tutorial to generate one, copying and pasting lines into your terminal, breathing a sigh of relief when your output didn’t have any obvious errors, and then never touching it again once the system seemed to be working. Maybe you’ve already used one today while you were pushing code to your favorite hosting service. But still, you don’t really know what an SSH key is.

How do you feel about this?

I’m intrigued and want to know more!

I think this sounds like a lot of trouble for a fancy password.

I’m desperate; please just tell me what to do!


Give Me Some Theory, But Only a Little

When you were in elementary school, you might have come up with a secret system for passing notes to your friends that the rest of the world couldn’t read. Maybe you used a simple substitution cipher, wherein you replaced every letter in your message with a particular number, and shared the number-letter correspondence graph only with your inner circle. Perhaps you did something more clever and added noise to the signal, like replacing every letter with an arbitrarily-chosen word ending in that letter.

No matter what encryption scheme you chose, it almost certainly had the following property: anyone who know the scheme could both encrypt and decrypt messages. For example, if you know that to encrypt a message, you replace the letter “C” with the number “12”, it’s obvious that decrypting the message involves replacing all occurrences of “12” with “C” – so obvious that it may never have occurred to you to think of the encryption and decryption schemes as distinct pieces of information.

In cryptography, these schemes are referred to as symmetric: the knowledge required to perform an operation is the same as that required to reverse it. As a sprog, any secret code you came up with was almost certain to be symmetric, because the operations we learn in elementary-level mathematics that don’t lose information are almost all trivially reversible.

However, it is possible to come up with an asymmetric scheme where the decryption process cannot be inferred from the encryption process, and vice versa. These schemes rely on functions whose inverses are mathematically well-defined, but would require impractically vast amounts of processing power to actually compute.

At first, it doesn’t sound very useful to encrypt a message that you yourself cannot decrypt. But if you’re communicating with a wide network that you don’t entirely trust, asymmetric encryption becomes very interesting.

Imagine a symmetric encryption scheme as the key to a lockbox. Cryptographic functions can be reused endlessly, which means that in this analogy lockboxes are free and abundant, as long as you have the keys to operate them. What a world!

You can write a message, lock it in the box, and send it to your friend. If your friend has a copy of the key, they can unlock the box and read its contents. You haven’t given a key to the mail carrier, so they cannot read the message even if they have full possession of the box for a while.

An asymmetric scheme, then, is a pair of keys. One key turns the lock only to the left, and the other only to the right. Although the lock turns both ways, the box can only be opened when it is perfectly centered.

You take one of the keys - say, the one that turns to the right - and deem it your private key. There is only one copy, and you keep it in your possession at all times. The one that turns to the left is your public key. This one you are promiscuous with. You give a copy to all your friends. You give a copy to all your enemies. You leave copies laying around on bulletin boards with your name attached. Anyone who wants your public key can get it with a minimum of effort. Verifying that a key with your name on it is actually your public key and not an imposter’s is a problem, but for the purposes of this page let’s assume that it’s solved.

Anyone in the world can now securely send you a message by placing it into one of your boxes, turning the key to the left, and mailing it to you. Because you have the only key that can turn the lock back to the right, the message in transit is safe from prying eyes.

On the other hand, you can place a message into one of your own boxes, turn the key to the right, and send it to a friend. This does not provide any privacy, because anyone in the world can turn the lock back to the left. But it does mean that your friend, upon receipt of the message, can be confident that it was written by you and is not a forgery - because to read the message, they had to unlock the box with your public key, and only messages locked with your private key can be unlocked with your public key.

When you generate SSH keys, they always come in public/private pairs, which exist as files on your computer. For our purposes, you can think of a particular private key as the encryption function for an asymmetric scheme, and its corresponding public key as the decryption function.

That’s Peachy, But I Just Need to Log Into Something

Unlike some other kinds of keys, SSH keys aren’t really about encrypting swaths of text; they’re for authenticating users to servers. The user, whom we will call Keira, has a private key, and every server that knows about Keira holds the corresponding public key. In drastically simplified form, the exchange goes a little like this:

The only information the server ever receives about Keira is a name, a public key, and the signed version of a random number that the server has freshly generated. This number, called a nonce by cryptographers, will never be used to authenticate Keira again, so it’s not interesting to hackers. None of the information sent to or stored on the server is sensitive!

This means that there is nothing on the server that can be used to compromise Keira’s identity in the event of a data breach – not even a password to the server in question. That’s not to say that such an authentication system is unhackable; a compromised session in progress can still be used to do some nefarious things. But in general such acts are more difficult and less rewarding to the attackers than stealing a password would be.

With password-based authentication, the exchange looks like this:

  • PAT: Hi, I’m Pat and my password is ‘dolphin’.
  • SERVER: The password you provided matches the password I have for Pat, so you must be Pat.

This is a lot simpler than key authentication, especially from the client’s perspective. Pat doesn’t have to respond to a different challenge at every login, and doesn’t have to figure out which cryptographic protocol the server speaks. Pat gets to just shove a password down the pipe and let the server do all the hard cryptographic work. That’s part of why password-based schemes are the predominant form of login for web-based applications: cryptographic protocols are updated and deprecated frequently, and web standards are a quagmire of terribleness where nothing can be deprecated ever because Sales would be furious if you squeezed users out of the marketing pipeline by updating the servers to a crypto protocol that isn’t supported by Mosaic 2.1. TLS manages to work, barely, by virtue of its existence completely outside the UX.

The tradeoff is that with a password, you have to trust the server to actually do the hard cryptographic work of salting your password, hashing it, and storing it in a vault with poison darts and a giant rolling boulder that keeps hackers away. Since private keys never leave your hands, you can even use them across multiple servers and it’s basically safe, unlike reusing passwords which is always a bad idea.

On the other hand, it’s hard to get users to care for SSH keys properly due to a lack of understanding. Fortunately, I’ve made a web page for that.

If I Say I’m Convinced, Will You Tell Me What to Give My Sysadmin Already?

Okay, but the rest of the page is pretty interesting so if you skipped straight to this section you should go back and give it a read sometime.

Firstly, if you’ve been through this before and have taken good care of your keys in the mean time, you can probably just reuse the keypair you already have. Go dig up your .pub file and send it over. You’re done.

The rest of you should generate a 2048-bit RSA key, unless you’ve been instructed otherwise. RSA is the most common type of keypair in use today, and while the ideal key length is debateable, conventional wisdom is that 2048 bits is the sweet spot for now and the near future. We’ll be saving the key in PEM format, which is compatible with a wide range of software. To do that, open up a terminal and type this in: If you’re on Windows, you’ll first need to either install OpenSSH or, for the full “IT won’t let me install another OS and I’m making the best of it” experience, set up WSL. Both of these features are built into Windows 10 these days but are disabled by default. Search around Microsoft’s site to find out how to enable them. If you’re running an older version of Windows, or you need your keys in a format not supported by OpenSSH, you’ll need to use third-party software, and then you’re on your own.

ssh-keygen -m pem -t rsa -b 2048

The program will ask you where to save the key. The default is $HOME/.ssh/id_rsa and many utilities will look for it there, so go with that.

It will ask you to put a passphrase on the key. Make up a good one and type it in a couple times.

Sending passwords (or passphrases; they’re the same thing) over the network when you don’t have to is bad. But storing secrets on your hard disk unencrypted is also bad.

Entering a passphrase here will symmetrically encrypt the private key file on your machine. You’ll need to enter it each time you use your private key (more or less), but it will never get sent to a remote server.

A passphrase isn’t required, but it’s a good idea to have one if you’ll be using the key for anything sensitive. If you lose your laptop, or accidentally share your home directory over the network, or let your kid’s weird friend who knows 300 digits of pi borrow your computer and then all your files end up on BitTorrent, having a passphrase will buy you some time to set up a new set of keys before cyberninjas crack open all your accounts like so many eggs.

If you really want to live on the edge, you can leave the passphrase blank.

You may see some nice abstract art. If your friends are around, you should observe this thoughtfully for a moment, perhaps while gently swirling a glass of heady red wine, because you don’t want to look like a philistine.

The file at $HOME/.ssh/id_rsa, or whatever path you entered, is your private key. Your public key will have the same path, but with the extension .pub attached.

Send the public key to your colleagues, so they can put it on the server you need to log into. Send it to your friends so you can trade messages like cryptographically-well-versed grade schoolers. Send it to your mom. Send it to your gym instructor. Broadcast it towards Alpha Centauri in case any friendly aliens are listening. Send it to anyone who might need to verify that you are you.

Don’t send the private key to anyone. If it doesn’t end in .pub, your sysadmin doesn’t need it. Your boss doesn’t need it. If your boss does want your private key, they’re up to something nefarious. Make a new key and hand over that one instead. Nobody in the #engineering Slack channel needs it, unless you want them and also all of Slack’s employees to be able to authenticate to your work machines as you. Your email provider doesn’t want your private key. Your priest doesn’t want your private key. Your dog doesn’t want your private key. And above all, I most certainly do not want your private key.

Please, please don’t ever send me your private key.