Juan Valencia's Website

Passwordless SSH using digital signatures

When we log in via SSH to a remote computer, usually a server, a way to authenticate with it that does not require the use of a password is the use of digital signatures. What we do in this case is to generate a key pair (a public key and a private key), and then add our public key to the list of authorized keys in the server that we want to be able to log into.

The first thing that we do is to create a key pair in the computer from which we will access the SSH server:

ssh-keygen -t rsa -b 2048

This will create two files, one called id_rsa which is our private key, and one called id_rsa.pub which is our public key. After this, we just need to add our public key to the list of authorized keys in the SSH server. This file is located in ~/.ssh/authorized_keys

A way to do this is to simply upload the file id_rsa.pub to the server, and then concatenate the contents of the file into ~/.ssh/authorized_keys. If the file authorized_keys, or the folder .ssh does not exist, you can create the folder with mkdir and the file with touch, although the cat command itself would create the file if it doesn't previously exist.

scp ~/.ssh/id_rsa.pub user@domain:~/
ssh user@domain
ls -d .ssh || mkdir .ssh
cat id_rsa.pub >> ~/.ssh/authorized_keys
rm id_rsa.pub

Another way to do it it's to use the commands together in one single (but long) command:

cat ~/.ssh/id_rsa.pub | ssh user@domain 'ls -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys'

Once this is done, don't forget to give to this folder and file the appropriate permissions, or else another user in the same system as you may just add a key to your file of authorized keys and this user would be able to log in via SSH into the system as you.

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

And we are done, in the future I will write an extensive explanation of how exactly does this work, with graphics an all, but for the moment the important thing here is that, information which is encrypted with our private key can only be decrypted by our public key, and information that is encrypted with our public key can only be decrypted by our private key.

Digging deeper

As you may already know, there are two protocols of SSH, the old implementation (protocol 1) and the most recent and better implementation (protocol 2). I am not sure why would anyone continue allowing access to a legacy SSH implementation that can only use the first protocol, but, I'm sure there are some that find it useful, personally I only allow the second protocol.

There are two algorithms for digital signatures that can be used for authentication in SSH, RSA (Rivest, Shamir and Adleman; it's named after it's creators) and DSA (Digital Signature Algorithm), neither algorithm is deprecated so you may use either one of them. DSA keys are faster signing, but slower verifying, than RSA keys.

For RSA, a 1536-bit key pair is recommended, ssh-keygen can generate RSA keys between 768 and 2048 bits for the use of SSH protocols version 1 and 2, and it can generate DSA keys of 1024 bits (only of this size due to a specification) for the use of SSH protocol version 2, by default a RSA key is generated for the use of SSH protocol 2.

The use of this keys is merely for authentication with the server when you log in, once you are logged in, a different type of encryption is used so what you do is secure from snooping.

Using DSA instead of RSA

If you prefer to use DSA for authentication with the server, you can use the following commands (yes, you may imagine then by now, but it's easier to copy paste):

ssh-keygen -t dsa

This will generate the files id_dsa (your private key) and id_dsa.pub (your public key), and then we just add the key to authorized_keys by method 1:

scp ~/.ssh/id_dsa.pub user@domain.tld:~/
ssh user@domain.tld
ls -d .ssh || mkdir .ssh
cat id_dsa.pub >> ~/.ssh/authorized_keys
rm id_dsa.pub

Or method 2:

cat ~/.ssh/id_dsa.pub | ssh user@domain.tld 'ls -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys'