Authentication is the process of determining whether someone or something is who or what it declares itself to be.

When we build systems, the problem of authentication comes up in two main contexts:

  • When a user tries to authenticate to a computing system (user-to-system).
  • When a system tries to authenticate to another system (system-to-system).

User-to-system authentication

When we discuss user-to-system authentication, there are three main categories of approaches in which authentication can be performed, known as authentication factors. We will discuss these factors in the following section:

The knowledge factors

The knowledge factors correspond to something the authenticated entity knows. For example, this could be a password or the answer to a question.

The ownership factors

The ownership factors correspond to something the authenticated entity has. For example, this could be an ID card or a hardware authentication device.

The inherence factors

The inherence factors correspond to something the authenticated entity is or does. For example, this could be a biometric identifier, such as a fingerprint or DNA.

Achieving the highest degree of security

To achieve the highest degree of security, a system should ideally use multiple authentication factors, a technique known as multi-factor authentication.

Example

Two-factor authentication (2FA) is an example of multi-factor authentication. Many applications nowadays use two-factor authentication (2FA).

In two-factor authentication (2FA), the user needs to provide a password first, and then they receive a one-time code in a personal device that they have to provide back to the system. In this way, even if the password of the user gets compromised, a malicious actor will be unable to access the system on behalf of the user without also getting access to their personal device.

Practices to follow when doing password-based authentication

There are several good practices when doing password-based authentication.

Avoid storing the password in plaintext

The system should avoid storing the password in plaintext so that it is not readily accessible to system administrators and cannot get leaked in case the database gets compromised.

One way to mitigate this issue is to compute the hash of the password and store the value instead. Even in that case, though, the attacker might be able to compute the original value of the password by precomputing a table of hashes for many possible values and then checking all the leaked hashes against this table. This process is known as a rainbow attack.

To make rainbow attack computationally harder, one can make use of a salt.

Salt is a random piece of data generated for every password and appended to the password before calculating the hash value. It can be stored alongside the password hash so that the same operation can be repeated when trying to authenticate an existing user.

Salt makes rainbow attacks harder to execute because the attacker would have to calculate every possible combination of the salt with all the possible passwords. One cannot do this in advance, but only after discovering some salts, e.g., due to a data leak. These are some of the many good practices we can follow to store passwords more securely.

System-to-system authentication

In system-to-system authentication, the knowledge and ownership factors are the ones that are mainly used.

For example, system AA might create an account with credentials for a separate system BB. These credentials might be injected at runtime on system BB, which will provide them to system AA in order to authenticate before invoking any operations. Alternatively, system AA might register public keys for other systems that can use the corresponding private keys for authentication (e.g., in SSH).

Get hands-on with 1400+ tech skills courses.