Understanding SSH Keys and using Keychain to manage passphrase on macOS Jul 3 2019

Accessing remote servers using passwords has been discouraged for a long time, and it is suggested to use SSH public keys as the authentication method. I've noticed that for some users, the setup and maintenance of their keys becomes a problem, so they go back to using passwords. In this post, I'll explain how to use SSH keys to login to remote servers and how to set up your SSH configuration to keep track of your keys using the macOS keychain.

The problem with passwords

Transmitting your password through the internet to connect to a remote server is dangerous. The password can be intercepted, or you can be tricked into sending it to a server pretending to be the real server. It doesn't matter how but the problem is that the password is being transmitted and if intercepted it can be used by anyone to impersonate you.

It would be nice if you could establish a connection to a server and then prove that it is you by answering a series of questions that only you can answer. To make it harder, the questions change, and only you can answer those questions correctly. That is the idea behind using key pairs, let's have a look.

Key pairs

To understand key pairs, first, let's talk about some basic concepts. SSH keys come in pairs, a public key and a private key. Your public key is the one that you give anyone that wants to identify you, with the public key anyone can decrypt messages coming from you. And the messages you send are encrypted using your private key. Keep your private key secret, store it securely somewhere that only you can access it, this one is never shared.

Ok, we have two keys, a public key and a private key, let's see how all this works.

How does it work?

When you connect to a server using SSH, the server sends you their public key, so you can also verify it's identity.

Let's assume you configured the server to know your public key, and you have the public key of the server. We will see later how to do that setup. The two parties (you and the server) have each other's public key, which means that each of you can decrypt any message coming from each other.

To make it clear, only you can write an encrypted message (using your private key) that the server can decrypt using your public key. And only the server can write an encrypted message (using the server's private key) that you can decrypt with the server's public key. That is the basis of the trust, if you can decrypt the message using the public key, it means that the message was encrypted using the pair private key.

Now what happens is that the server can question you, to see if you are who you say you are, the conversation (handshake in network parlance) would be something like this:

The connection is established, and you can communicate trusting that each party is who they say they are.

That was an oversimplification of how it works, but it should give you enough of a mental model to understand the concept of key pairs. Now let's go back to generating the keys in our computers and use them.

SSH key generation

On macOS, we can use ssh-keygen utility to generate a new key pair. You'll be prompted for a passphrase when you create the keys. If you don't set a passphrase anyone that has access to your private key file can read it. I encourage you to use a passphrase, it is a good security habit. We'll add the passphrase to your Keychain later, so you won't have to type the passphrase every time you use the key.

To generate a key pair you can use the following command, just change the file names and comment as you wish:

$ ssh-keygen -t rsa -b 4096 -C " key for derik@rderik.com" -f ~/.ssh/id_rderikcom

The -t flag sets the type of key, we are going to use rsa, that means, that the key is going to use the RSA algorithm to generate the encryption of the key. The -b specifies the number of bits in the key, the minimum is 1024, anything below that can be cracked by brute force easily and is not secure. To be safe, let's quadruple the complexity and use 4096 bits. The flag -C adds the comment key for derik@rderik.com to our public key, that is only a comment to make it easier for us to identify the public key, but it's just that, a comment.

This will generate the two keys (in the directory ~/.ssh):


As you can imagine, the filename with the extension .pub is the public key, the one that you'll be sharing with anyone that want's to authenticate you. Now let's add your ssh key to the server, so you no longer have to type your password to login to the server.

Adding your public key to the server

Copy your public key to your clipboard with the following command:

$ cat ~/.ssh/id_rderikcom.pub | pbcopy

That will save the key in your clipboard, assuming your key is in id_rderikcom.pub. When I created mine, I used a custom name, if you did the same just change the file but only use the public key ( the one with the .pub extension). Now connect to the remote server to add your key to the authenticated keys.

$ ssh your_user@server.test

This time the server will prompt you for your password because we haven't added the public key yet. So login to the server with your password and create the ~/.ssh directory.

$ mkdir -p ~/.ssh

You might not have the .ssh directory in your home, that is why we are creating it. If it is already there, that command will do nothing, the -p flag will check if its already created.

The server uses the authorized_keys file inside your users home ~/.ssh/ directory to verify if a key is valid. So let's add our key to the authorized_keys file:

$ vi ~/.ssh/authorized_keys

Now, paste your public key in that file, make sure only one key exists per line. Your public key should be your clipboard. Save and exit (:wq). That's it, log out(Ctrl-d, or type exit) and test it. Try to reconnect to the remote server:

$ ssh your_user@server.test

And you should be logged in, you shouldn't be prompted for the password. Remember, you won't be asked for a password by the server, but if you set a passphrase, you'll be prompted for it. We are going to remove the need to type the passphrase using your macOS Keychain.

Use Keychain to store passphrases

The Keychain on macOS can be used to keep track of our internet usernames and passwords, certificates, keys passphrases, etcetera. We are going to tell ssh to use the Keychain as the ssh-agent so it can obtain the passphrase from the Keychain. The configuration for ssh is stored on the file ~/.ssh/config. Let's see some examples of possible configurations:


#If you want to use the same identity file and configuration for any domain use a * wildcard
 Host *
  AddKeysToAgent yes
  UseKeychain yes
# if you used a custom name for your identity file, use that name here
  IdentityFile ~/.ssh/id_rsa 

# If you want to have a different identity file for each project you can specify it by domain or IP
Host server.test
 AddKeysToAgent yes
 UseKeychain yes
 IdentityFile ~/.ssh/id_rderik_server_test

 AddKeysToAgent yes
 UseKeychain yes
 IdentityFile ~/.ssh/id_rderik_server2_test

That's it, the next time you use ssh to connect to the remote server, you won't be asked for the passphrase.

Final Thoughts

Sometimes when we don't have a clear picture of what is going on is hard to implement changes that we know are good for us. I hope that this post helps someone out there to understand how key pairs work and change from using passwords to always using SSH public keys to authenticate.

Aside from the security benefit, it makes it faster and more efficient not to have to type passwords and automatically be logged in to the server.

I would like to point out that you can create as many key pairs as you want, there is nothing special about them. When I started using SSH keys, I had the misconception that once I created a key, I would have to stick with that key forever. As you saw, it is easy to create new key pairs and easy to add them to the servers. You can also create one key pair for your laptop, one for your desktop, one for your phone, etc. you don't need only to have one key and copy it on all your environments.

Let me know if you liked the post or if you have any comments.

Related topics/notes of interest:

IgnoreUnknown UseKeychain
    UseKeychain yes

** If you want to check what else I'm currently doing, be sure to follow me on twitter @rderik or subscribe to the newsletter. If you want to send me a direct message, you can send it to derik@rderik.com.