DEV Community

loading...

Securing and Storing Passwords

Linas Spukas
Full-stack web developer with a specialisation in React and NodeJS.
・3 min read

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)

Discussion (2)

Collapse
calvinsadewa profile image
calvinsadewa

Use unique salt for every password before hashing

What do you think about adding pepper too?

Collapse
spukas profile image
Linas Spukas Author

Pepper will provide an additional layer of protection. Unlike salt, pepper will remain the same for all the hashes and it will not be exposed and kept as a secret, probably somewhere in the configuration file of the app. The con of using pepper is long term maintenance. If pepper for some reason will be compromised or you decide to change it, all the passwords, hashed with pepper, will be invalid and require to change. I guess most of the time hashing with salt provides a great balance between security and convenience :)