Password Hashing
Password hashing is a method used to protect passwords stored in databases or systems from being accessed by unauthorized parties. This cryptographic process transforms a password into another fixed-length value known as a hash, which ideally cannot be reversed or decrypted to reveal the original password.
History and Context
The concept of hashing passwords has roots back to the early days of computing where simple encryption methods were used. However, as computers became more powerful and cryptographic attacks more sophisticated, the need for more secure methods became evident:
- In the 1970s, UNIX systems started using simple hash functions like DES (Data Encryption Standard) for password storage. These were later found to be vulnerable to preimage attacks.
- By the 1980s, systems began to incorporate salt (random data) into the hash to prevent pre-computed attacks like rainbow tables. One of the first implementations was in UNIX's crypt(3) function.
- The 1990s saw the introduction of more robust hashing algorithms like MD5 and SHA-1, although these too were later found to have weaknesses when used for password hashing.
- Modern approaches now favor algorithms specifically designed for password hashing, such as bcrypt, scrypt, and Argon2, which are designed to be slow and computationally expensive to thwart brute-force attacks.
Key Concepts
Salting
Salting involves adding a unique, random string of characters to each password before hashing. This makes the hash unique even if two users have the same password, complicating dictionary and rainbow table attacks. The salt should be stored alongside the hash, as it's not secret but rather used to ensure uniqueness.
Work Factor
The work factor, often known as the cost parameter, defines the computational cost of hashing. Increasing this value makes the hash function take longer to compute, providing more resistance against brute-force attacks. For example, in bcrypt, this is known as the 'cost' parameter.
Hash Functions for Passwords
Not all hash functions are suitable for password storage due to their speed and design:
- bcrypt: Designed by Niels Provos and David Mazières in 1999, bcrypt uses the Blowfish cipher in a way that makes it very slow. This slow computation is intentional to thwart brute-force attacks. Source.
- scrypt: Developed by Colin Percival in 2009, scrypt is designed to be memory-intensive, making it harder to implement in hardware (like ASICs) for cracking passwords. Source.
- Argon2: The winner of the Password Hashing Competition in 2015, Argon2 comes in three variants, each with different memory and time trade-offs. It's designed to be resistant to side-channel attacks. Source.
Implementation Considerations
- Use a sufficient work factor to balance security with performance.
- Always use a unique salt for each password.
- Regularly update the hashing algorithm when vulnerabilities are found or when hardware capabilities increase.
- Never store passwords in plain text or use reversible encryption.
References