Node.js  

How to Store Passwords Securely Using Bcrypt in Backend Applications?

Introduction

Passwords are the first line of defense in most applications. If they are stored incorrectly, even a small data breach can expose thousands—or millions—of user accounts. This is why storing passwords securely is not just a best practice, it is a fundamental requirement for any backend system.

A common mistake developers make is storing passwords as plain text or using simple hashing methods. In real-world scenarios, this can lead to serious security issues. Instead, we use a technique called hashing with Bcrypt, which is specifically designed to store passwords safely.

In this article, we’ll understand how password security works, why Bcrypt is widely used, and how to implement it properly in backend applications.

Why Storing Passwords in Plain Text is Dangerous

Let’s start with a simple example.

If your database stores passwords like this:

  • user1 → password123

  • user2 → admin@123

If a hacker gains access to your database, all passwords are immediately exposed. Users who reuse passwords across platforms are especially at risk.

Even hashing with basic algorithms like MD5 or SHA256 is not enough anymore, because attackers can use precomputed tables (rainbow tables) or brute-force attacks to crack them quickly.

This is where Bcrypt comes in.

What is Bcrypt?

Bcrypt is a password hashing algorithm designed specifically for security.

Unlike simple hashing algorithms, Bcrypt:

  • Adds a random salt to each password

  • Is intentionally slow (making brute-force attacks difficult)

  • Automatically handles salting and hashing together

In simple terms, even if two users have the same password, their stored hashes will be different.

How Bcrypt Works

When you store a password using Bcrypt:

  1. A random salt is generated

  2. The password is combined with the salt

  3. The result is hashed multiple times

  4. The final hash is stored in the database

When a user logs in:

  • The entered password is hashed again

  • Compared with the stored hash

At no point is the original password stored or retrievable.

Installing Bcrypt in Node.js

npm install bcrypt

Hashing Passwords Before Storing

Here’s how you securely store a password:

import bcrypt from 'bcrypt';

const saltRounds = 10;

async function hashPassword(password) {
  const hashedPassword = await bcrypt.hash(password, saltRounds);
  return hashedPassword;
}

What this does:

  • Generates a salt internally

  • Hashes the password

  • Returns a secure hash

Storing Password During User Registration

const registerUser = async (req, res) => {
  const { email, password } = req.body;

  const hashedPassword = await bcrypt.hash(password, 10);

  // Save to database
  await User.create({ email, password: hashedPassword });

  res.send("User registered successfully");
};

In real applications:

  • You never store the plain password

  • Only the hashed version is saved

Comparing Passwords During Login

When a user logs in, you compare the entered password with the stored hash.

const loginUser = async (req, res) => {
  const { email, password } = req.body;

  const user = await User.findOne({ email });

  if (!user) {
    return res.status(404).send("User not found");
  }

  const isMatch = await bcrypt.compare(password, user.password);

  if (!isMatch) {
    return res.status(401).send("Invalid credentials");
  }

  res.send("Login successful");
};

Why this is secure:

  • Password is never decrypted

  • Comparison happens securely using hashes

Real-World Scenario: What Happens in a Data Breach

If your database is leaked:

  • With plain text → attacker instantly gets passwords

  • With Bcrypt → attacker only gets hashes

Since Bcrypt is slow and salted:

  • Cracking each password takes significant time

  • Mass attacks become impractical

This gives your system a strong layer of protection.

Choosing the Right Salt Rounds

saltRounds controls how strong the hashing process is.

  • Higher value → more secure but slower

  • Lower value → faster but less secure

Typical recommendation:

  • 10–12 for most applications

Example:

const saltRounds = 12;

Bcrypt vs Other Hashing Methods

FeatureBcryptMD5 / SHA
SaltingBuilt-inManual
SpeedSlow (secure)Fast (insecure)
Brute-force ResistanceHighLow
Recommended for PasswordsYesNo

Common Mistakes Developers Make

  • Storing passwords without hashing

  • Using fast hashing algorithms (MD5, SHA1)

  • Using very low salt rounds

  • Logging passwords in console

  • Sending passwords in plain text over HTTP (always use HTTPS)

Best Practices for Password Security

  • Always hash passwords using Bcrypt

  • Use strong salt rounds (10+)

  • Never store or log plain passwords

  • Use HTTPS for all API calls

  • Implement rate limiting on login endpoints

  • Add account lockout after multiple failed attempts

Advanced Security Enhancements

For production-grade systems, combine Bcrypt with:

  • JWT authentication

  • Multi-factor authentication (MFA)

  • Password strength validation

  • Secure session management

Real-World Use Cases

  • User authentication systems

  • Banking applications

  • E-commerce platforms

  • SaaS applications

Anywhere user data is involved, password security is critical.

Conclusion

Storing passwords securely is one of the most important responsibilities of a backend developer. Bcrypt provides a reliable and industry-standard way to protect user passwords against modern attacks.

By hashing passwords, using proper salt rounds, and following best practices, you can significantly reduce the risk of data breaches and protect your users’ sensitive information.

Security is not just about writing code—it’s about building trust. A secure authentication system is the foundation of any successful application.