Password and API secret hashing
LivePasswords use scrypt, a memory-hard function, with parameters stored in each hash so they can be raised later.
API keys carry about 190 bits of entropy, so a keyed HMAC is used instead of a slow hash. Because the HMAC key lives outside the database, a database leak alone cannot be used to test candidate keys offline.
- Password KDF
- scrypt, N = 2^15 (32,768), r = 8, p = 1, 64-byte output
- Salt
- 16 random bytes per password; input normalized to NFKC; 10–256 characters
- Stored as
scrypt$15$8$1$<salt>$<hash>- Timing
- Unknown accounts are checked against a dummy hash; comparison uses timingSafeEqual
- API key format
proj_live_+ 32 base62 characters from rejection sampling (no modulo bias)- API key stored as
- Lookup prefix (
proj_live_+ 8 characters) andHMAC-SHA256(API_KEY_HASH_SECRET, "api-key:v1:" + key) - Verification
- Prefix lookup, then constant-time comparison, which also runs on a lookup miss
- Disclosure
- The full key is shown once at creation and cannot be retrieved again