How To Generate an SSH Key

There are several scenarios where you might need SSH keys. Some very prominent use-cases a developer might encounter:

  • Remote access to a server with SSH,
  • Git(Hub) deploy key to grant access to a single repository and
  • Signing files.

Warning: This post uses an outdated algorithm. Please check GitHub Docs Generating a new SSH key for an up to date instructions.

In the following example, we will generate an RSA key with the ssh-keygen tool.

RSA (Rivest–Shamir–Adleman) - a very common cryptosystem. Since the public key is for encryption and the private key for decryption its so-called asymmetric encryption.

Please see the post Using AES with OpenSSL to Encrypt Files for a sample of symmetric encryption.

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/devop/.ssh/id_rsa): sample_id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in sample_id_rsa.
Your public key has been saved in sample_id_rsa.pub.
The key fingerprint is:
SHA256:nT1o2jRiziTVJQM70ySkfB5evSr1wrtoZeWNah45n+M devop@laptop.local
The key's randomart image is:
+---[RSA 2048]----+
|       .+.+ .    |
|     . . * =     |
|      o B + .    |
|       = * +..   |
|      . S Oo+o   |
|       * Oo=o..  |
|        =oO..    |
|        .oo*..   |
|       ..o+oE.   |
+----[SHA256]-----+

Two new files appeared in the working directory:

-rw-------  1 devop   wheel  1675 Nov 29 10:33 sample_id_rsa
-rw-------  1 devop   wheel   406 Nov 29 10:33 sample_id_rsa.pub

You can easily spot the public key with the additional .pub in the filename.

A private key usually looks like this:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA4BldLWoDCTE8vn6JQgmpmYBja7VZrcqtpZ65qNpes98rOO2b
…
10D7RStVIHlZgziP46cVLNtBw99+6F0TewQsRnxnJvHxLOaop/AU
-----END RSA PRIVATE KEY-----

and the public key:

ssh-rsa AAAAB3NzaC1yc2EA…MiWKVIj9Tj devop@laptop.local

Note: You can also check SSH keys with the file command.

$ file sample_id_rsa.pub
sample_id_rsa.pub: OpenSSH RSA public key

Remote access

Add the public key id_planets_rsa.pub to the servers authorized_keys inside .ssh directory, and you can access the remote server without entering a password:

ssh -i ~/.ssh/id_planets_rsa planets@cloud-provider

Deploy keys

Allow your continuous integration pipeline to access a (private) repository via deploy keys. Give the public key to your Git provider (e.g. GitHub) and use the corresponding private key to allow your Jenkins to clone the repository.

Note: In such a scenario you’ll have to generate an SSH key without a passphrase.

Signing

Given you want to verify the digest of file message.txt that has been signed with a private key. Additionally, the signed digest is base64 encoded.

First you need to decode the base64 encoded digest:

openssl enc -base64 -A -d -in message.txt.sig.base64 > message.txt.sig

With the digest decoded you can verify the file with the public key (in PKCS #8 format):

$ openssl dgst -sha256 -verify sample_id_rsa.pub.pem -signature message.txt.sig message.txt

Verified OK

If everything is in place you’ll get a Verified OK.

Converting to PKCS #1 and PKCS #8

Sometimes you need the public key to have a special format like PKCS #1 or PKCS #8.

At first sight, both keys look the same. On second sight you can spot the difference: An additional RSA in the enclosing comment.

Converting to PKCS #1/PEM:

$ ssh-keygen -f sample_id_rsa.pub -e -m pem
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA4BldLWoDCTE8vn6JQgmpmYBja7VZrcqtpZ65qNpes98rOO2bS54t
LgJ5Pldl4xRvGgIyXlogyML0RlGHNvSswHaN5rQFbJQVDreF0d+1fvuEIqeSqHlk
…
i0MC6ePFMHY+wAImdturG8lg37VMxBGwOti/c5Da8Dm9NFV1oVs+fVlEfuACL+2w
o5C4Vr9/C3NhfHU1+N6JqDAjIlilSI/U4wIDAQAB
-----END RSA PUBLIC KEY-----

or PKCS #8

ssh-keygen -f sample_id_rsa.pub -e -m pkcs8
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4BldLWoDCTE8vn6JQgmp
mYBja7VZrcqtpZ65qNpes98rOO2bS54tLgJ5Pldl4xRvGgIyXlogyML0RlGHNvSs
…
y6ZjAfyeZaA2kG8wgE1z5O+DJc36Hnl3i0MC6ePFMHY+wAImdturG8lg37VMxBGw
Oti/c5Da8Dm9NFV1oVs+fVlEfuACL+2wo5C4Vr9/C3NhfHU1+N6JqDAjIlilSI/U
4wIDAQAB
-----END PUBLIC KEY-----

Another interesting side-note: You can always extract the public key from your private key:

$ openssl rsa -in sample_id_rsa -pubout -out sample_id_rsa.pub.pkcs8
writing RSA key

This command will give you the public key in PKCS #8 format.


🙌 Photo by Sixteen Miles Out on Unsplash