What are SSH keys?

SSH in textured text on a textured black background

The internet's greatest strength is also its biggest drawback: it's permissive. Its early architects favored connectivity over authentication, and many of the tools and protocols they developed reflected that approach. They used plain text to access remote resources — a security nightmare because anyone listening in would get the keys to the kingdom.

As the world evolved, people developed newer standards to make the net more secure. Secure shell (SSH) is one of them. It appeared in 1995 as a replacement for Telnet and other protocols that granted access to resources over a network.

SSH lets you access any network resource securely, including servers, which you can log into via SSH and use as though they were local machines. This is great for administration over a LAN or a suitably protected WAN connection. You can use it to copy files securely between machines and forward ports from one machine to another. You can even use it to run some graphical interfaces remotely.

Because it's an open protocol, SSH can underpin any other service to make its remote connections more secure. A good example is Git, the source code management system that Linus Torvalds developed.

Git uses HTTPS to push repositories to remote servers, but you can switch to SSH for a more convenient connection that doesn't need password authentication. The same goes for GitHub, the online source code management site that uses Git.

You can also use SSH for secure one-shot terminal commands like scp (secure copy). This command uses SSH under the hood to copy files between machines, although the OpenSSH community has officially deprecated it.

Alternatively, an SSH-protected version of the ftp protocol called sftp offers a community-blessed if more complex solution.

Understanding public key cryptography

SSH secures the connection using public key cryptography. First conceived in the 1970s, this exchanges data using two digital files called keys. They enable two parties to communicate in secret without meeting physically.

Imagine Bob and Alice live a long way apart. They want to talk secretly to each other, but they know Eve is trying to listen in. Alice creates a secret code that she and Bob can use to encrypt and decrypt messages, but she can't send it to him because Eve will intercept it.

Instead, Bob creates two digital keys, one public and one private. The public key can encrypt messages that only the private key can decrypt.

Bob posts the public key everywhere, including on his website and at the foot of all his emails. He also guards the private key closely.

Alice uses the public key to encrypt a message that she sends to Bob. Eve has also seen the public key, but she can't use it to decrypt the message. Only Bob can read that data.

Alice also creates her public and private keys. Now, Bob can use her public key to encrypt messages and send them to her too.

Stopping imposters

So far, so good. Eve can't read encrypted messages from Bob or Alice. There's a problem, though. If Eve has Bob's public key, she could encrypt her own messages and send them to Bob while pretending to be Alice. Because she also has Alice's public key, she could also impersonate Bob.

We can solve that problem using a special property in public key cryptography. If Bob reverses things and encrypts a message with his private key, then his public key can decrypt it. That might seem pointless at first, because everyone can see the public key, so anyone can decrypt the message.

On closer inspection, this quality proves valuable. Bob's public key decrypts only messages encrypted using his private key and nothing else. Because only Bob has access to the private key, it means any message his public key decrypts must have come from him. It proves his identity and stops imposters.

To prove he is the author of his encrypted messages, Bob can encrypt a message with Alice's public key, and then encrypt it again with his private key. If Eve tries to replace it with her own message, Alice won't be able to decrypt it with Bob's private key, and she'll know that it's bogus.

How SSH uses keys

That's the basic principle of public key cryptography, and SSH uses it to establish secure communication sessions on a network. Default SSH configuration generates the key pair automatically after prompting you for a password. It then shares the public key with the server, using in future sessions when you enter the right password.

This password-based approach isn't advisable. The attacker could mount a man-in-the-middle attack by asking the user for the password they're using to set up the connection and storing it themselves before forwarding it to the server. This would only work if the attacker intercepts the first ever SSH session between a client and server because the server will store the automatically generated keys for subsequent sessions.

Passwords are generally insecure when used as the only means of authentication, though. SSH runs over port 22 as standard, which online ne'er-do-wells will happily try to brute force password access to all day. Why give them the opportunity? Disabling password-only access is a good practice when working with SSH.

Manual key generation

A far more secure solution is to manually generate your own SSH keys and get the public key to the server securely.

You can generate SSH keys using the ssh-keygen command. This will create a key, storing it in the ~/.ssh folder. Assuming you've stayed with the default file names, you'll see a private key in that folder called id_rsa and a public one called id_rsa.pub. The public key is the one you share with your destination server. The private key is the one that you keep secure. If anyone gets a hold of it, they can access your SSH connections.

For extra security, you can specify a passphrase to protect your private key. Ssh-keygen gives you this option as part of its process. Passphrase protection is less convenient because you must enter it every time you use your SSH key, but it provides another barrier to stop someone who gets access to your machine from using your SSH connections.

Simply having that key pair on your client isn't enough. You must copy it to the destination server. The server stores the public key on its own line in the ~/.ssh.authorized_keys file, which enables it to store multiple keys and therefore grants access to multiple clients.

When a client makes an SSH connection request with its private key, the server will check this file for the corresponding public key. If it's there, it'll encrypt a string with it and send it to the client as a challenge.

The client then decrypts that string with its private key and combines it with a session ID that both parties know. It creates an MD5 hash of these two items that it sends back to the server.

The server, which has the same two pieces of information, also hashes them. If its hash matches the one from the client, the server knows the client's key is valid and grants the client access.

Getting the public key onto the server is relatively easy. You can use a utility called ssh-copy-id on Linux systems to copy the file across and install it in the right place. Alternatively, you can copy it manually to the authorized_keys file via a password-based SSH connection. An alternative if you have physical access to the server is to copy it via physical media rather than using an SSH session.

SSH comes out of the box on most systems these days. The macOS and Linux operating systems have SSH installed already, and Windows has included the default OpenSSH client installed by default since the fall of 2018. You'll also need an SSH daemon installed on the server you want to access, which will listen for incoming connections.

There are dangers to consider when using SSH, though. One of them is key management. SSH keys don't expire by default, which is a problem when dealing with lots of clients. Before long, servers will become littered with SSH keys, which aren't easily tied to particular users. A proper system for key management is a must. You can use OpenSSH to create a simple certificate authority that can help with key management.

Key management also means securing your keys carefully. It’s easy to share them without thinking, even if you understand the importance of guarding your private key.

Developers happily commit their private SSH keys to GitHub by either forgetting to omit their SSH directory or perhaps deliberately including it. This makes those keys publicly accessible if the repositories are public — and many are. A simple Google search reveals them.

Used properly, SSH makes it faster, easier, and more secure to access network resources, especially if you use them a lot. Nothing's quite as satisfying as pushing to a remote repo and having it just work, no mess, no fuss.

Danny Bradbury

Danny Bradbury has been a print journalist specialising in technology since 1989 and a freelance writer since 1994. He has written for national publications on both sides of the Atlantic and has won awards for his investigative cybersecurity journalism work and his arts and culture writing. 

Danny writes about many different technology issues for audiences ranging from consumers through to software developers and CIOs. He also ghostwrites articles for many C-suite business executives in the technology sector and has worked as a presenter for multiple webinars and podcasts.