LUNAROPS · OPERATIONAL UPLINK 100% UPTIME 1,247d POSTS 893 JEFF.MOON@LUNAROPS.DEV UTC --:--:--

Password Security Done Right

passwordshashingauthenticationbcrypt

Password security seems simple but is often done wrong. Here’s how to handle passwords correctly.

Never Store Plain Text

This should be obvious, but breaches still reveal plain text passwords. Always hash.

Use the Right Algorithm

Good choices:

  • bcrypt
  • Argon2 (preferred for new projects)
  • scrypt

Never use:

  • MD5
  • SHA-1
  • SHA-256 alone (too fast)

bcrypt Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import bcrypt

# Hashing
password = "user_password".encode()
salt = bcrypt.gensalt(rounds=12)
hashed = bcrypt.hashpw(password, salt)

# Verification
if bcrypt.checkpw(password, hashed):
    print("Password matches")
1
2
3
4
5
6
7
8
// Node.js
const bcrypt = require('bcrypt');

// Hash
const hash = await bcrypt.hash(password, 12);

// Verify
const match = await bcrypt.compare(password, hash);

Work Factor Matters

The “rounds” or “cost” parameter controls how slow hashing is:

1
2
3
4
5
# ~100ms on modern hardware
bcrypt.gensalt(rounds=12)

# Adjust based on your server capacity
# Higher = more secure but slower

Password Requirements

Good policy:

  • Minimum 12 characters
  • Check against breached password lists
  • No complexity rules (they don’t help)

Bad policy:

  • Must have uppercase, lowercase, number, symbol
  • Maximum length (never limit this)
  • Forced rotation

Rate Limiting

Prevent brute force:

1
2
3
4
5
# After 5 failed attempts
if failed_attempts >= 5:
    # Lock account for 15 minutes
    # Or require CAPTCHA
    # Or exponential backoff

Additional Protections

Multi-Factor Authentication

Always offer MFA. TOTP is a good baseline:

1
2
3
4
5
6
7
8
9
import pyotp

# Generate secret for user
secret = pyotp.random_base32()

# Verify code
totp = pyotp.TOTP(secret)
if totp.verify(user_code):
    print("Valid")

Secure Password Reset

  • Time-limited tokens (1 hour max)
  • Single use
  • Invalidate on password change
  • Don’t reveal if email exists

Storage Checklist

  • Passwords hashed with bcrypt/Argon2
  • Sufficient work factor (>= 12 rounds)
  • Rate limiting on login
  • Account lockout after failures
  • MFA available
  • Secure password reset flow
  • No password in logs

Password security is foundational. Get it right from the start.

Comments