Back to top

Linux - SSH keys and SSH key generation

SSH keys and SSH key generation

Background and Terminology:

SSH - Secure Shell

SSH is both a program and a network protocol that provides strong authentication and secure encrypted communications between two machines over an insecure network. It is designed for logging into and executing commands on a remote machine, as well as moving files back and forth between the two machines. SSH has various authentication mechanisms and the most secure is based on keys rather than passwords. Using keys, SSH can authenticate you to all your computer accounts securely without the need to memorize many passwords or enter them repeatedly. SSH generates a private and a public key. The public key can be put on the machines you wish to communicate with. SSH will then connect to those machines with keys instead of your standard account password.

SSH protocols

SSH1 and the SSH-1 protocol were developed in 1995 by Tatu Ylonen, a researcher at the Helsinki University of Technology in Finland. It is still distributed and maintained, though not actively developed (bug fixes only). SSH2 and the superior SSH-2 protocol were released in 1998. SSH-2 is a commercial product, but is available free for use by qualifying educational entities.

Public-Key Algorithms used by SSH

The Digital Signature Algorithm (DSA) was developed by the U.S. National Security Agency (NSA), and promulgated by the U.S. National Institute of Standards and Technology (NIST) as part of the Digital Signature Standard (DSS). DSA can only be used to provide digital signatures and can't be used for encryption. DSA has an intrinsic weakness which makes it very easy to create a signature which contains enough information to give away the private key! The Rivest-Shamir-Adleman public-key algorithm (RSA) is the most widely used asymmetric cipher. RSA can be used for both encryption and digital signatures. It is currently difficult to obtain the private key from the public key.

Generating the SSH key pairs

In this tutorial there will be two machines represented:

[user_name@local_host ~]$

This will represent the user's account on the local machine - the machine that you are physically sitting in front of.

[user_name@remote_host user_name]$

This will represent the user's account on the remote machine - the machine that you will be accessing via ssh.

To create the public and a private keys, on the computer from which you will be connecting to various computers, generate SSH key pairs as follows (I recommend using the RSA algorithm):

[user_name@local_host ~]$ ssh-keygen -t rsa -b 2048

Generating public/private rsa key pair.

Note: The -t option specifies the type of the key to create. The possible values are:

  • rsa1 for SSH-1 protocol: The file in which you save the keys should be in /home/user_name/.ssh/identity
  • rsa for SSH-2 protocol: The file in which you save the keys should be in /home/user_name/.ssh/id_rsa
  • dsa for SSH-2 protocol: The file in which you save the keys should be in /home/user_name/.ssh/id_dsa

The -b option specifies the number of bits in the key to create. The minimum is 512 bits and the default is 1024 bits. Generally, 1024 bits is considered sufficient.

Enter file in which to save the key (/home/user_name/.ssh/id_rsa): [press enter]

If you get the following message after you press enter to save the key:

/home/user_name/.ssh/id_rsa already exists.
Overwrite (y/n)?

It means that an SSH key of that type was previously created. It is up to the user to decide whether or not to overwrite the existing key. It you decide to overwrite the existing key, any machine that you were previously accessing with key authentication will now fail.

Enter passphrase (empty for no passphrase): [press enter]
Enter same passphrase again: [press enter]

Note: The passphrase is basically the password for your key and the simplest approach is not to set a passphrase. For certain purposes, this is necessary (such as cron jobs) since no opportunity will be presented to provide passwords. Hence a passphrase-less key is called for.

There is a problem with this: if your private key is stored unprotected on your own computer (meaning an empty passphrase), then anybody who gains access to it will be able to generate signatures as if they were you. This is the reason your private key is usually encrypted when it is stored on your local machine, using a passphrase.

Your identification has been saved in /home/user_name/.ssh/id_rsa.
Your public key has been saved in /home/user_name/.ssh/id_rsa.pub.
The key fingerprint is:
1a:2b:3c:4d:5e:6f:7a:8b:9c:0d:1e:2f:3a:4b:5c:6d user_name@machine_name.compbio.cornell.edu
[user_name@local_host ~]$

There are two files generated: one with and one without the .pub extension. The one with .pub extension is your public-key and can be safely divulged. The other is your private-key and must be safeguarded from being read by others.

Now that you have generated your key, you will need to put your public key in the authorized keys file on all of the machines you want to connect to using ssh. You will do this using scp.

SCP (Secure Copy Program) is a utility which copies files between hosts on a network. It uses ssh for data transfer, and uses the same authentication and provides the same security as ssh.

The general form of the command is:

[user_name@local_host ~]$ scp source-specification destination-specification

In the case above we will use:

[user_name@local_host ~]$ scp /home/user_name/.ssh/id_rsa.pub remote_host.compbio.cornell.edu:/home/user_name/id_rsa.pub

SCP will prompt you for the password to the remote machine. After entering the password, the public key will be copied into your home directory on the remote machine.

Note: If this is the first time you have connected to this particular remote_host, you will see something like:

The authenticity of host 'remote_host (132.236.123.102)' can't be established.
RSA key fingerprint is 17:a7:ac:13:07:5b:5d:2b:d7:22:16:c7:61:01:20:33.
Are you sure you want to continue connecting (yes/no)?

Type yes and press enter if you are sure that you are connecting to the proper remote_host.

The next thing that we need to do is connect to the remote machine via ssh:

[user_name@local_host ~]$ ssh -l user_name remote_host.compbio.cornell.edu
user_name@remote_host.compbio.cornell.edu's password: [enter user_name password]

Now that we are on the remote_host, we need to concatenate the contents of the public key to a file called authorized_keys which is located in the .ssh directory of your home directory.

[user_name@remote_host user_name]$ cat /home/username/id_rsa.pub >> /home/username/.ssh/authorized_keys

[user_name@remote_host user_name]$ rm -f id_rsa.pub

Optional: Your authorized_keys file should now look something like this:

ssh-rsa AAAAB3NzaC1y ... gwWhN/sYw== user_name@machine_name.compbio.cornell.edu

If you are familiar with editing files using vi or emacs, you can add an additional security feature to the ssh key. By adding the hostname of the local machine from which you will be connecting to the ssh key, you further restrict machine access.

First, we need to obtain the hostname of the local machine:

[user_name@local_host ~]$ hostname
machine_name.compbio.cornell.edu

Next, we will add this information to the appropriate entry in the authorized_keys file:

[user_name@remote_host user_name]$ vi /home/user_name/.ssh/authorized_keys

Add the hostname information obtained above to the beginning of the appropriate key as such:

from="machine_name.compbio.cornell.edu"

The authorized_keys file should now look something like:

from="machine_name.compbio.cornell.edu" ssh-rsa AAAAB3NzaC1y ... gwWhN/sYw== user_name@machine_name.compbio.cornell.edu

Setting Permissions:

Lastly, we need to ensure that permissions are set correctly. The .ssh directory should have permissions of 700 and the authorized_keys file should have permissions of 644. SSH will totally ignore the keys if the permissions are not correct.

[user_name@remote_host user_name]$chmod 700 /home/user_name/.ssh

This will allow read, write and execute permissions on the directory for the owner, and give no permissions to everyone else.

[user_name@remote_host user_name]$chmod 644 /home/user_name/.ssh/authorized_keys

This will allow read and write permissions on the file for the owner, and give only read permissions to everyone else.

At this point, when you ssh into the remote machine you just copied your public (possibly edited) ssh key into, you will no longer be prompted for the user_name password.