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.
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:
Server: helo, I’m
server.orghere’s my public key
You: helo, I’m
Server: oh, are you
firstname.lastname@example.org? Well, I have you in my authenticated keys list, let’s see if it is you. Encrypt the following message with your private key: “there are no beginnings in the wheel of time”
You: ok, here it is: 9f046d240cb29e049adddb72dbeb0210
Server: ok, let’s see (the server uses your public key to decrypt the message and obtains: “there are no beginnings in the wheel of time”). Perfect! I believe your claim, you are
You: ok, but prove me that you are
server.org, encrypt “a silence of three parts”
Server: ok, here it is: 3c7c54f24058257ac5242d9e581a23e1
You: ok, let’s see(you use
server.orgpublic key to decrypt the message and obtain: “a silence of three parts”). Perfect! I believe it is you, let’s begin.
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:
1 $ ssh-keygen -t rsa -b 4096 -C " key for email@example.com" -f ~/.ssh/id_rderikcom
-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 firstname.lastname@example.org 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
1 2 id_rderikcom id_rderikcom.pub
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:
1 $ 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.
1 $ ssh email@example.com
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
1 $ 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
1 $ 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:
1 $ ssh firstname.lastname@example.org
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #~/.ssh/config #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 Host 10.0.0.1 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.
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:
You can use the
securitycommand to access information in your Keychain so you can automate tasks, check the
securityman page, or this link to read more about it https://ss64.com/osx/security.html
If you want to use the Security framework using swift check Apple’s Security Framework documentation
I wrote this Swift program that shows how to write and read from the Keychain, Keychain swift code. Let me know If you would like me to write a post explaining it.
An Interesting note on changes on OpenSSH updates from Apple for macOS 10.12.2, the Interesting part is:
1 2 IgnoreUnknown UseKeychain UseKeychain yes
- Now that you know how to copy your ssh keys to a remote server and understand the process, you could use the command
ssh-copy-idto achieve the same result, read the man page to learn more.