C# > Security and Cryptography > Cryptographic Operations > Storing Passwords Securely

Salting and Hashing Passwords with BCrypt

This snippet demonstrates how to securely store passwords using BCrypt, a widely respected password hashing algorithm. It includes salting to prevent rainbow table attacks.

BCrypt Password Hashing

This code defines a static class `PasswordHasher` with two methods: `HashPassword` and `VerifyPassword`. `HashPassword` uses BCrypt to hash the given password with a randomly generated salt. The salt is embedded within the hashed password string. `VerifyPassword` then checks if a given password matches the stored hashed password using the salt embedded within the hash.

using BCrypt.Net;

public static class PasswordHasher
{
    public static string HashPassword(string password)
    {
        // Generate a salt and hash the password
        string hashedPassword = BCrypt.Net.BCrypt.HashPassword(password, BCrypt.Net.BCrypt.GenerateSalt(12));
        return hashedPassword;
    }

    public static bool VerifyPassword(string password, string hashedPassword)
    {
        // Verify if the password matches the hash
        return BCrypt.Net.BCrypt.Verify(password, hashedPassword);
    }
}

Concepts Behind the Snippet

Password hashing is crucial for protecting user credentials. Storing passwords in plaintext is extremely dangerous. Hashing transforms the password into a one-way function, making it computationally infeasible to reverse the process and recover the original password. Salting adds a unique, random string to each password before hashing. This prevents attackers from using precomputed rainbow tables to crack passwords. BCrypt is an adaptive hashing algorithm, meaning its computational cost can be increased over time to keep pace with improving hardware. The '12' in `GenerateSalt(12)` refers to the work factor. A higher work factor increases the computational cost, making it harder to crack but also slightly slower to hash/verify.

Real-Life Use Case

Imagine a social media platform needing to securely store user passwords. This snippet provides a simple, yet robust, way to hash and store passwords in the database. When a user registers, their password would be hashed using `HashPassword` and stored. During login, the entered password would be compared to the stored hash using `VerifyPassword`. If they match, the user is authenticated.

Best Practices

Always use a strong hashing algorithm like BCrypt, Argon2, or scrypt. Use a unique salt for each password. Keep the salt secret is no longer a valid concern when using modern hashing algorithms like BCrypt where the salt is stored as part of the hash. Regularly rehash passwords as hashing algorithms improve. Use a sufficiently high work factor to make password cracking computationally expensive. Consider using a password complexity policy to encourage users to choose strong passwords.

Interview Tip

When discussing password security, highlight the importance of salting and hashing. Explain the vulnerabilities of storing passwords in plaintext or using weak hashing algorithms. Mention the adaptive nature of BCrypt and how the work factor can be adjusted to increase security.

When to Use Them

Use password hashing whenever you need to store user passwords or other sensitive data that should not be recoverable in its original form. It's a fundamental security practice for any application that handles user authentication.

Memory Footprint

The memory footprint of BCrypt is relatively small, primarily related to the size of the salt and the hash itself. It's generally not a significant concern unless you're hashing a very large number of passwords concurrently on a resource-constrained device.

Alternatives

Alternatives to BCrypt include Argon2 and scrypt. Argon2 is a modern, memory-hard algorithm that's a strong contender. scrypt is another key-derivation function designed to be computationally intensive. PBKDF2 is also an option, but generally considered less secure than BCrypt and Argon2.

Pros

  • Strong security against rainbow table attacks due to salting.
  • Adaptive, meaning the work factor can be increased over time to maintain security.
  • Relatively simple to implement.
  • Widely supported and well-vetted.
  • Cons

  • Can be slower than some other hashing algorithms, especially with a high work factor.
  • The speed can be seen as a pro since it prevents rapid brute-force attacks.
  • FAQ

    • Why is salting important?

      Salting adds a unique, random string to each password before hashing, preventing attackers from using precomputed rainbow tables to crack multiple passwords at once. Without salting, if two users have the same password, their hashed passwords will also be identical, making them vulnerable to rainbow table attacks.
    • What is a 'work factor'?

      The work factor in BCrypt controls the computational cost of the hashing process. A higher work factor increases the time it takes to hash and verify a password, making it more resistant to brute-force attacks, but also slightly slower for legitimate users.
    • Is BCrypt the best password hashing algorithm?

      BCrypt is a very good and widely used option. Argon2 is considered a modern alternative that offers similar or potentially better security, especially in memory-hard environments. The 'best' algorithm can depend on your specific requirements and threat model.