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