Securing and Storing Passwords
Tags: security, passwords, beginners
Published: 2020-02-09 14:05:51

Many software applications do not correctly protect the sensitive data of the users. Weakly implemented authentication will allow attackers to steal, expose or modify personal data, like emails, passwords, financial data, credit cards.
Educating and following best practices for securing passwords for the software applications would be the first steps to minimize sensitive data exposure. This article will explain and try to convince to use hashing for keeping passwords safe.


## Hashing

**Hashing** is a one-way function. Meaning if you hash something, there is no way to convert it back. For example, if you would hash a password 111 with an algorithm that produces a product of 333 and store that hash in the database, in case of a data leak, the attacker cannot convert it back to your original password.

## Cracking a Hash

While the hash cannot be transformed back, it can be 'cracked'. The attacker can take a password candidate, run through the same algorithm and compare the product with the stolen one. And this is being repeated many times. To make it even easier and efficient, there already exists a large amount of pre-computed hashes, stolen from the compromised sites, so the attacker would need to just check the hashes, sparing the high cost of computations running the algorithm. The database of these hashes is called **rainbow tables**.
The process of cracking is not assured to be successful. It very depends on how secure, unique and strong your password is, what algorithm used and what work factor set for an algorithm to compute the hash.


## Salting

To make the hash very unique and significantly difficult to guess for an attacker, a little piece of randomly generated text is added to the password. This piece of random text is called **salt**. Password combined together with salt (with a simple concentration) is run through an algorithm and produced hash is saved in the database.
Salt should be generated randomly and uniquely for every password. This will make for an attacker impossible to check the hash against rainbow tables and would have to guess salt and password to see if the hashes match.
Salt does not have to be a secret and usually is stored together with the hash, added to the front or back of the hash, or stored in the same database. The most important aspect of the salt is it has to be unique and as random as possible.
Modern algorithms, like Bcrypt or Argon2 is adding salt to passwords automatically and you do not need to take care of it. Though you have an option to do it manually:

- Generate at least 16 characters long salt with cryptographic secure functions (i.e. Crypto in Node.js)
- Encode salt into hexadecimal or Base64 character
- Concatenate salt with the password
- Hash combination with an algorithm (i.e. Bcrypt)
- Save hash in the database one of two ways:
    - Add salt to the front or back of the hash
    - Store hash and salt in separate fields of the database

## Algorithms

There are several modern algorithms, that are specifically designed for securely hashing passwords and should be taken into consideration when choosing:
- Bcrypt - it is the most popular and supported algorithm, it is simple to use and should be the first option unless very specific requirements needed
- Argon2 - won hashing algorithm competition in 2015. It takes more configuration parameters and needs deeper knowledge to set it correctly
- PBKDF2 - has implemented FIPS-140 (Federal Information Processing Standards) requirements for cryptographic modules. It is included in the .NET framework

## Work Factor

Each algorithm can be configured how slow it should run. This configuration is called **work factor** and it is included in the hash. The purpose of the work factor is to make algorithms slow, to reduce the time for an attacker to calculate a hash and make the calculation work computationally expensive.
Work factor is a number of iterations the algorithm has to run on each password. The number counts to `2^n`, for example, Bcrypt default work factor is 10.
The slower algorithm is, the more difficult for an attacker to crack the hash, but should be taken into consideration that the same applies to the user, who tries to login and the same amount of time it takes to recompute and compare hashes. So the balance should be between the demand and speed.

## Summing Up

Securing users private data should be one of the main priorities. Hashing passwords before storing is highly recommended. It will minimise the risk for attackers to steal and compromise sensitive data. Before storing passwords make sure to:
- Use Bcrypt algorithm as a default unless specific configuration needed
- Set a balanced work factor for an algorithm
- Use unique salt for every password before hashing (modern algorithms does that for you)