# ADR-0018: Password Hashing Algorithm ## Status Accepted ## Context The platform needs to securely store user passwords. Requirements: - Resist brute-force attacks - Resist rainbow table attacks - Future-proof against advances in computing - Reasonable performance (not too slow) Options considered: 1. **bcrypt** - Battle-tested, widely used 2. **argon2id** - Modern, memory-hard, recommended by OWASP 3. **scrypt** - Memory-hard, good alternative 4. **PBKDF2** - Older standard, less secure ## Decision Use **argon2id** for password hashing with recommended parameters: - **Algorithm**: argon2id (variant) - **Memory**: 64 MB (65536 KB) - **Iterations**: 3 (time cost) - **Parallelism**: 4 (number of threads) - **Salt length**: 16 bytes (random, unique per password) **Rationale:** - Recommended by OWASP for new applications - Memory-hard algorithm (resistant to GPU/ASIC attacks) - Good balance of security and performance - Future-proof design - Standard library support in Go 1.23+ ## Consequences ### Positive - Strong security guarantees - Memory-hard (resistant to hardware attacks) - OWASP recommended - Standard library support ### Negative - Slightly slower than bcrypt (acceptable trade-off) - Requires tuning parameters for production ### Implementation Notes - Use `golang.org/x/crypto/argon2` package - Store hash in format: `$argon2id$v=19$m=65536,t=3,p=4$salt$hash` - Use `crypto/rand` for salt generation - Verify passwords with `argon2.CompareHashAndPassword()` - Consider increasing parameters for high-security environments