working with ssh-keygen



~7 min read


1213 words

Update: Adding a section on the PEM format as it was a particularly painful lesson recently and I burned a several hours tracking down the answer. Thank you to Brian Redbeard on Stack Exchange for pointing me in the right direction!

SSH, also referred to as Secure Shell, is a protocol for authenticating services remotely. See’s SSH Protocol article for more.

I’ve had to set up too many machines recently and each time, this is a learning curve. So, I’ll be documenting my process for generating SSH keys on MacOS, with some attention toward the ssh-config toward the end:

Generating A New SSH Key

The simplest way to generate a new SSH Key is to open a terminal and type:

$ ssh-keygen

The ssh-keygen utility “generates, manages and converts authentication keys for ssh.”

The default key is generated using the RSA Cryptosystem. This will prompt you with a few questions:

  1. Enter the file in which to save the key (the default is /.ssh/id_rsa)
  2. Enter passphrase (empty for no response)
  3. Enter same passphrase again If you just keep pressing Enter, eventually you’ll see an output like:
Your identification has been saved in /Users/stephen/.ssh/id_rsa.
Your public key has been saved in /Users/stephen/.ssh/
The key fingerprint is:
The key's randomart image is:
+---[RSA 3072]----+
|.+B+             |
|+oo*     . .     |
|=.=Eo   . +      |
|+= . o o *       |
|+o. . . S .      |
|o o.   B.+       |
|o. .  ..o=o      |
|+ .    .*...     |
|o.      .o..     |

That means you successfully created a new public/private key.

Passing Options

While the default approach will work fine, there are some convenient flags that are worth knowing: -C adds a comment. This is appended to the public key, which can make it easier to identify. For example, Github recommends adding your email address for use here. -b sets the bits in the key. The default is 3072, which is “generally […] considered sufficient”, however can be raised and lowered as needed. -f sets the file name of the output key file -t specifies the type of key that’s created (rsa-sha2-512 is the default) -m sets the key format (default is Open SSH, but some older systems may require that you use PEM)

So, for example, this can look like:

ssh-keygen -t rsa -b 4096 -C "This is a comment" -f <the_file_name>

PEM Format And Converting SSH Keys

Some systems cannot process the Open SSH format and may require that the key is the PEM format.

If you know this in advance, you can create a new public/private key specifying the format upfront:

$ ssh-keygen -t rsa -b 4096 -m PEM -C "This is a comment" -f <the_file_name>

Alternatively, if you have to convert the public/private key after it’s been created, you can use the -e flag:

ssh-keygen -f <the_file_name> -e -m PEM

Reviewing SSH Keys

Now that we’ve created it, let’s make sure it exists. If you used the default id_rsa, then it’s likely that your key is in the .ssh directory of your user (i.e., ~/.ssh).

You can verify that you have both a public and private key by listing the contents of that directory:

$ ssh-keygen -t rsa -b 4096 -C "<>" -f id_github_rsa
$ ssh-keygen -t rsa -b 4096 -C "<>" -f id_work_github_rsa
$ ssh-keygen -t rsa -b 4096 -C "<>" -f id_gitlab_rsa
$ ls -la ~/.ssh
total 48
drwx------   8 stephen  staff   256 Apr 27 13:47 .
drwxr-xr-x+ 49 stephen  staff  1568 Apr 27 16:58 ..
-rw-r--r--   1 stephen  staff    84 Mar 11 18:58 config
-rw-------   1 stephen  staff  3389 Mar 11 18:54 id_github_rsa
-rw-r--r--   1 stephen  staff   751 Mar 11 18:54
-rw-------   1 stephen  staff  3389 Mar 11 18:54 id_work_github_rsa
-rw-r--r--   1 stephen  staff   751 Mar 11 18:54
-rw-------   1 stephen  staff  3389 Mar 11 18:54 id_gitlab_rsa
-rw-r--r--   1 stephen  staff   751 Mar 11 18:54
-rw-------   1 stephen  staff  2635 Apr 27 13:47 id_rsa
-rw-r--r--   1 stephen  staff   589 Apr 27 13:47
-rw-r--r--   1 stephen  staff  3353 Apr 24 16:47 known_hosts

Setting Up the SSH Config

Now that we’ve created multiple accounts, it’s time to set up the ssh config (here’s the manual page with all of the options)

This might look like:

  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_github_rsa
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_work_github_rsa
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_gitlab_rsa

Some notes and caveats:

  1. If you don’t know add the keys to the ssh-agent, it can be:

     IdentityFile ~/.ssh/id_github_rsa
  2. If the host is the same as the hostname (as the case for the personal account), you should be able to get away with:

     IdentityFile ~/.ssh/id_github_rsa
  3. Instead of a subdomain for the host, I’ve also seen appending the user name, for example:

     IdentityFile ~/.ssh/id_work_github_rsa

(Remi Lavedrine put together a great walkthrough on Dev.To which I found as I was pulling this together. )

(Optional) Adding SSH Keys to ssh-agent

ssh-agent is a program to hold private keys used for public key authentication (RSA, DSA, ECDSA, Ed25519). ssh-agent is usually started in the beginning of an X-session or a login session, and all other windows or programs are started as clients to the ssh-agent program. Through use of environment variables the agent can be located and automatically used for authentication when logging in to other machines using ssh(1).

Github has put together a nice step-by-step guide on how to add a key to the ssh-agent.

Make sure that the ssh-agent is running:

$ eval "$(ssh-agent -s)"

Then, once you’re done setting up the SSH Config (the previous step), add the new id to the agent:

$ ssh-add -K ~/.ssh/id_rsa

Testing that you’ve connected

If you’ve made it this far, it’s worth testing that your ssh connect is working as expected. One way to do that is with ssh -T.1 For example:

$ ssh -T

This will attempt to use the user git to access (which was the Host we specified in the user specific config file above). GitHub offers some handy debugging tips if this doesn’t work (e.g., if you receive an error permission denied (public key)).

Wrap Up

That should be plenty for now. Typically, if a service has an option for connecting via SSH, it will provide documentation for where to put your public key, but what to do with the private key is a little bit more of a mystery. Hopefully this answers some of those questions.

Reference Material


  • 1 The use of the -T flag is really to ensure the terminal does not attempt TTY. From the manual:

       -T      Disable pseudo-terminal allocation.
       -t      Force pseudo-terminal allocation.  This can be used to execute arbitrary screen-based
               programs on a remote machine, which can be very useful, e.g. when implementing menu
               services.  Multiple -t options force tty allocation, even if ssh has no local tty.

Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!