Skip to main content
Skip to main content
SecurityMay 10, 20268 min read

Building a Complete Password Encryption System

From user password to encrypted data storage. A complete solution for secure applications.

Build secure password systems with our Password Tools. Learn best practices for hashing and encryption.

The Database Breach

It is Monday morning. You are sipping coffee when the security alert hits your inbox. Your user database has been leaked. Millions of passwords exposed.

But here is the twist: the attacker only got hashes, not plaintext passwords. And you used bcrypt with proper salt. Those passwords are still safe.

This is the difference between good and bad password storage. Let us explore how to do it right.

Hashing vs Encryption: Critical Difference

Passwords should never be encrypted. They should be hashed. Here is why:

Encryption is reversible. If someone gets the key, they can decrypt all passwords. Hashing is one-way. You cannot unhash a password.

When a user logs in, you hash their input and compare it to the stored hash. If they match, the password is correct. You never need to know the actual password.

Choosing the Right Algorithm

Not all hash algorithms are suitable for passwords. Here is what to use and what to avoid:

  • Use bcrypt - Industry standard, adaptive cost factor, built-in salt
  • Use Argon2 - Winner of Password Hashing Competition, memory-hard
  • Use scrypt - Memory-hard, good for cryptocurrencies
  • Never use MD5 - Broken, too fast, vulnerable to rainbow tables
  • Never use SHA-256 - Designed for speed, bad for passwords
  • Never use plain text - Unacceptable in any circumstance

Understanding bcrypt

Bcrypt is the most widely recommended password hashing algorithm. It has several key features that make it ideal for passwords.

First, it is slow. Bcrypt includes a cost factor (work factor) that makes hashing intentionally slow. This prevents brute force attacks. A cost factor of 10-12 is recommended for most applications.

Second, it automatically handles salt. Salt is random data added to each password before hashing. This prevents rainbow table attacks. Bcrypt generates and stores the salt automatically.

Implementation Guide

Here is how to implement password hashing in different languages:

Node.js (bcrypt)

const bcrypt = require('bcrypt'); const saltRounds = 12; // Hash password const hash = await bcrypt.hash(password, saltRounds); // Verify password const match = await bcrypt.compare(password, hash);

Python (bcrypt)

import bcrypt # Hash password password = b'super secret password' salt = bcrypt.gensalt(rounds=12) hashed = bcrypt.hashpw(password, salt) # Verify password if bcrypt.checkpw(password, hashed): print('Match')

Common Password Storage Mistakes

Even experienced developers make these mistakes:

  • Using fast hash algorithms - SHA-256, MD5 are designed for speed, making brute force easy
  • Not using salt - Without salt, identical passwords have identical hashes
  • Hardcoding salt - Salt must be unique per password, randomly generated
  • Insufficient cost factor - Too low and hashing is too fast; too high and it affects performance
  • Storing passwords in logs - Never log passwords, even for debugging

FAQ

Q.What is pepper?

A.Pepper is a secret key added to all passwords before hashing, unlike salt which is unique per password. It provides extra security if the database is leaked but the pepper key remains safe.

Q.How do I migrate to a better algorithm?

A.Rehash passwords on next login. When a user logs in with the old hash, verify it, then rehash with the new algorithm and store the new hash.

Q.Does password length matter with hashing?

A.Yes. Bcrypt truncates passwords at 72 bytes. Encourage users to use long passwords, but consider pre-hashing very long passwords if necessary.