Public key Authentication

Public key authentication is a method in which a user proves their identity by using a cryptographic key pair consisting of a public key shared with the server and a private key kept secret.

In public-key authentication, the user has the private key, and the server has a corresponding public key. This key pair is usually generated together on the users’ system using SSH tools. The public key is then copied to the server into the user’s profile before the user can authenticate.

When the user connects to the server, the server sends a challenge message to the user. The user uses the private key to sign the challenge message and returns the signature to the server. The server uses the public key to verify the signature. If the signature is valid, the user is authenticated and granted access to the server.

Why not use a password?

Using a username and password is classic and still used for multiple systems. Still, they have weaknesses that public key authentication addresses, which means if supported by the environment, public key authentication is generally considered the better option over classic passwords.

Attackers can hack passwords using brute force and other methods.

Passwords are sent “over the wire” and could be intercepted and potentially compromised (especially if the channel is not encrypted).

And public key solves these problems how?

Private keys are cryptographic, which is far more challenging to hack than an average password, a relatively short text string.

Private keys are never transmitted, and without the private key, you cannot log on to the system. Private keys are secured on a system; the attacker would need to have gained access to the system to retrieve the private key.

What are SSH Keys

SSH keys are a cryptographic pair; public and private. The client has the private key, and the server has a copy of the public key.

You can freely share the public key, which is not a security risk. You must always secure the private key, which must be protected and never shared.

Before logging on to a server, the user’s public key must exist on an authorized users file. The server uses the public key as part of a challenge-response process to validate that the connecting user owns the public key.

Usernames or profiles are generally still required. They provide the ability to manage the authorization layer, such as what the user authenticated by the key pair can do once logged in. It’s also typically where the public key is saved to.

Challenge-response process

A user attempts to connect to a server configured with a profile and the user’s public key; the server sends a message called a challenge to the user.

This challenge is a random string of characters the user must sign with their private key to prove their identity.

The user’s computer uses a cryptographic algorithm, such as RSA or DSA, and the private key to create a digital signature, which only the corresponding public key hosted on the server can verify.

This digital signature is sent back to the requesting server.

The server uses the user’s public key to verify the signature.

If the signature is valid, the server knows that the user is who they claim to be and grants them access to the server.

Since the challenge is a random string of characters generated by the server, an attacker cannot simply guess the challenge or replay a previous challenge to try to gain access to the server. This helps to prevent unauthorized access and protects the user’s account and data.

User keys

Typically the user generates an SSH key pair that includes public and private keys that are stored on their connecting system.

By default, the public key is named id_rsa.pub, and the private key is called id_rsa.

The default file names can be changed to whatever you like, which is needed if you use different keys for different SSH services, as described below.

The default folder where the keys are saved is in the user’s home directory in a specific default folder, which most operating systems refer to as ~/.ssh.

The default folder can be changed, but it is not recommended as specific security conditions must exist for a system to trust the private key, plus most SSH systems use the default folder.

If you need to connect to multiple SSH services from the same client, using a different SSH key pair for each service or server you connect to is recommended. If one of your private keys is compromised or stolen, you don’t want the attacker to be able to use that private key to access all of your other services or servers. Using separate keys gives you more flexibility and control over access to different systems. For example, you can easily revoke access to a specific system by deleting the corresponding key pair without affecting your access to other systems.

Server keys

A server uses its key pair in SSH to authenticate to clients and encrypt the data sent between the server and the client. When a client connects to the server for the first time, you’ll often see a warning message about the public key offered by the server, which must be accepted to make the connection.

The client uses the server’s public key to encrypt a random symmetric key to encrypt the data sent between the client and the server.

The server also uses its private key to sign any data it sends to the client, which allows the client to verify that the data is authentic and has not been tampered with.

The server typically generates the SSH key pair during the initial installation of the SSH server software.

The server stores the public key in a file on the server, usually in the /etc/ssh/ directory, and named ssh_host_rsa_key.pub for RSA keys. The server also stores the private key in the /etc/ssh/ directory and names it ssh_host_rsa_key for RSA keys.

Changing the file names or folder paths is not recommended.

The root user owns the private key file, which is only readable by the root user, as it contains sensitive information.

The SSH server daemon (service) uses the private key file to encrypt outgoing and incoming messages during SSH connections.

Demo setting up a VM and a new user

For a user to connect to an SSH server using public key authentication, the user must first have an account on the server with a home directory where the user’s public key can be stored. This example VM has a user created during the VM creation, called adminuser that uses a password. We will logon as this user to first create the new user and then configure the new user so they can logon with public keys.

This is based on a Windows 11 client device

Generate a user key pair

On the client device generate a key pair by opening a terminal session and running the following command ssh-keygen as per the example below. This will generate the public and private key pair with the default names in the defaut location.

PS ~> ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\grinntec/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\grinntec/.ssh/id_rsa.
Your public key has been saved in C:\Users\grinntec/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:05gOIdQIwrjYvzvzvxzcvbzfv8zdz87cvhscvsy7weef grinntec@workstation
The key's randomart image is:
+---[RSA 3072]----+
|+ ...+oo.        |
|.o .o ooo*.=.   .|
|.+ ....     o+..o|
|o =  . o * .++o..|
| o      S o o.. .|
|       o .   . + |
|        .     o.o|
|              ..o|
|               . |
+----[SHA256]-----+
PS ~>

Create the new user and setup the public key

First you need to log onto the server as the adminuser with the password.

PS ~> ssh adminuser@50.104.144.17
The authenticity of host '50.104.144.17 (50.104.144.17)' can't be established.
ECDSA key fingerprint is SHA256:Il0NkeHWcGvSsdga<adfafs54ssr/effalC7oFKFE3XIg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '50.104.144.17' (ECDSA) to the list of known hosts.
adminuser@50.104.144.17's password:
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1105-azure x86_64)

adminuser@vm-sshdoc-4a41:~$

Now create the new user profile. We don’t want a password, which is the default prompt, so we use the command below which create a new user named “newuser” with no password and a home directory in the default location (/home/newuser).

sudo useradd -m -s /usr/sbin/nologin newuser

Create the ./shh folder in the new user’s home directory. You need to do this as adminuser as the newuser does not have a password so you cannot use the profile.

sudo useradd --create-home --shell /bin/bash appuser

Switch to the new user.

sudo su - appuser

Create a .ssh directory in the new user’s home directory:

mkdir -p ~/.ssh

Create a authorized_keys file in the .ssh directory:

touch ~/.ssh/authorized_keys

Open the authorized_keys file in a text editor:

nano ~/.ssh/authorized_keys

Paste the contents of the public key file for the user into the authorized_keys file. You can do this by copying the contents of the public key file on your Windows 11 machine and pasting them into the text editor on the Linux server.

Save and exit the file (in Nano, press Ctrl+X, then Y, then Enter).

Set the correct permissions on the .ssh directory and the authorized_keys file:

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

Exit the new user’s account:

exit

Now the new user can log in to the server using their private key, without being prompted for a password.

ssh appuser@50.104.144.17
Last modified July 21, 2024: update (e2ae86c)