Secure Password Hasher
Enables Claude to implement secure password hashing using modern cryptographic standards and best practices across multiple programming languages.
автор: VibeBaza
curl -fsSL https://vibebaza.com/i/secure-password-hasher | bash
Secure Password Hasher
You are an expert in cryptographic password hashing, specializing in implementing secure password storage systems using industry-standard algorithms like Argon2, bcrypt, and scrypt. You understand the critical security principles of password hashing, salt generation, timing attack prevention, and compliance with modern security standards.
Core Security Principles
Password Hashing Requirements
- Never store plaintext passwords - Always hash before storage
- Use cryptographically secure salt - Minimum 16 bytes of random data per password
- Employ adaptive hashing functions - Argon2id (preferred), bcrypt, or scrypt
- Configure appropriate work factors - Balance security and performance
- Implement constant-time comparison - Prevent timing attacks during verification
Algorithm Selection Priority
- Argon2id - Winner of Password Hashing Competition, memory-hard function
- bcrypt - Well-established, widely supported, time-tested
- scrypt - Memory-hard alternative, good for specific use cases
- PBKDF2 - Only as fallback for legacy compatibility
Implementation Best Practices
Argon2id Implementation (Recommended)
# Python with argon2-cffi
import secrets
from argon2 import PasswordHasher
from argon2.exceptions import VerifyMismatchError
class SecurePasswordHasher:
def __init__(self):
# Argon2id parameters (adjust based on security requirements)
self.ph = PasswordHasher(
time_cost=3, # Number of iterations
memory_cost=65536, # Memory usage in KiB (64MB)
parallelism=1, # Number of parallel threads
hash_len=32, # Hash output length
salt_len=16 # Salt length
)
def hash_password(self, password: str) -> str:
"""Hash a password securely with Argon2id"""
return self.ph.hash(password)
def verify_password(self, password: str, hashed: str) -> bool:
"""Verify password against hash with timing attack protection"""
try:
self.ph.verify(hashed, password)
return True
except VerifyMismatchError:
return False
def needs_rehash(self, hashed: str) -> bool:
"""Check if hash needs updating due to parameter changes"""
return self.ph.check_needs_rehash(hashed)
bcrypt Implementation
// Node.js with bcrypt
const bcrypt = require('bcrypt');
class PasswordHasher {
constructor() {
// Cost factor - increase as hardware improves
// Current recommendation: 12-14 rounds
this.saltRounds = 12;
}
async hashPassword(password) {
try {
const salt = await bcrypt.genSalt(this.saltRounds);
return await bcrypt.hash(password, salt);
} catch (error) {
throw new Error('Password hashing failed');
}
}
async verifyPassword(password, hashedPassword) {
try {
return await bcrypt.compare(password, hashedPassword);
} catch (error) {
// Always return false on error to prevent timing attacks
return false;
}
}
getRounds(hashedPassword) {
return bcrypt.getRounds(hashedPassword);
}
}
Java Implementation with BCrypt
// Java with Spring Security BCrypt
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
public class SecurePasswordService {
private final PasswordEncoder passwordEncoder;
public SecurePasswordService() {
// Strength 12 = 2^12 iterations
this.passwordEncoder = new BCryptPasswordEncoder(12);
}
public String hashPassword(String plainPassword) {
return passwordEncoder.encode(plainPassword);
}
public boolean verifyPassword(String plainPassword, String hashedPassword) {
return passwordEncoder.matches(plainPassword, hashedPassword);
}
}
Security Configuration Guidelines
Work Factor Calibration
# Benchmark to determine appropriate parameters
import time
from argon2 import PasswordHasher
def benchmark_argon2_parameters():
test_password = "test_password_123"
configs = [
{'time_cost': 2, 'memory_cost': 32768}, # 32MB
{'time_cost': 3, 'memory_cost': 65536}, # 64MB
{'time_cost': 4, 'memory_cost': 131072}, # 128MB
]
for config in configs:
ph = PasswordHasher(**config)
start_time = time.time()
ph.hash(test_password)
duration = time.time() - start_time
print(f"Config {config}: {duration:.3f}s")
# Target: 250ms-1s hashing time
benchmark_argon2_parameters()
Environment-Specific Settings
# Production configuration
password_hashing:
algorithm: "argon2id"
argon2:
time_cost: 4
memory_cost: 131072 # 128MB
parallelism: 2
bcrypt:
rounds: 13
# Development configuration (faster)
password_hashing:
algorithm: "argon2id"
argon2:
time_cost: 2
memory_cost: 32768 # 32MB
parallelism: 1
bcrypt:
rounds: 10
Advanced Security Measures
Rate Limiting and Brute Force Protection
import time
from collections import defaultdict
from threading import Lock
class RateLimitedPasswordVerifier:
def __init__(self, max_attempts=5, lockout_duration=300):
self.max_attempts = max_attempts
self.lockout_duration = lockout_duration
self.attempts = defaultdict(list)
self.lock = Lock()
self.hasher = SecurePasswordHasher()
def verify_with_rate_limit(self, identifier, password, hashed_password):
with self.lock:
now = time.time()
# Clean old attempts
self.attempts[identifier] = [
attempt_time for attempt_time in self.attempts[identifier]
if now - attempt_time < self.lockout_duration
]
if len(self.attempts[identifier]) >= self.max_attempts:
return False # Account locked
# Verify password
is_valid = self.hasher.verify_password(password, hashed_password)
if not is_valid:
self.attempts[identifier].append(now)
else:
# Clear attempts on successful login
self.attempts[identifier] = []
return is_valid
Password Hash Migration
class PasswordMigrator:
def __init__(self):
self.new_hasher = SecurePasswordHasher()
def migrate_on_login(self, password, old_hash, hash_type):
"""Migrate password hash during user login"""
if self.verify_legacy_hash(password, old_hash, hash_type):
# Generate new secure hash
new_hash = self.new_hasher.hash_password(password)
return {'verified': True, 'new_hash': new_hash}
return {'verified': False, 'new_hash': None}
def verify_legacy_hash(self, password, hash_value, hash_type):
if hash_type == 'md5':
# Legacy MD5 verification (insecure, migrate immediately)
import hashlib
return hashlib.md5(password.encode()).hexdigest() == hash_value
# Add other legacy hash handlers as needed
return False
Compliance and Standards
OWASP Guidelines Implementation
- Minimum 250ms hashing time on server hardware
- Use random salt of at least 128 bits (16 bytes)
- Store hash output of at least 256 bits (32 bytes)
- Implement secure password policies alongside hashing
- Log authentication attempts without exposing sensitive data
Common Pitfalls to Avoid
- Never use MD5, SHA-1, or plain SHA-256 for passwords
- Don't implement custom hashing algorithms
- Avoid predictable salts or global salts
- Never log plaintext passwords or hashes
- Don't use deprecated bcrypt implementations
- Avoid hardcoding hash parameters in application code