A salt is a unique, random value mixed into a password before it is hashed. Salting is what stops two users who happen to choose the same password from sharing the same stored hash, and it makes precomputed attacks such as rainbow tables useless because the attacker would need a separate table per salt. Modern password hashing functions — bcrypt, scrypt, Argon2, PBKDF2 — all require a salt, and it must be generated from a cryptographically secure source. This tool produces salts using the Web Crypto API entirely in your browser.
How it works
The generator allocates a byte buffer and fills it with random data from crypto.getRandomValues, the browser’s cryptographically secure pseudo-random number generator:
- Allocate a
Uint8Arrayof your chosen size (16 bytes by default). - Fill it with
crypto.getRandomValues(bytes)— neverMath.random. - Encode the raw bytes as hex or base64 for storage.
You then store this salt alongside the resulting password hash. Salts are not secret: their security comes from being unique and unpredictable, so it is completely safe to keep them in plain text next to the hash.
How salts fit into a password hashing flow
A salt does not hash the password itself — it is mixed in before hashing so that the final hash is unique to that specific (password + salt) combination. The flow at registration:
1. Generate salt: crypto.getRandomValues(16 bytes)
2. Encode: toHex(salt) or toBase64(salt)
3. Hash: argon2id(password + salt, workFactor)
4. Store: {hash, salt} in the database — salt in plaintext
At login verification:
1. Retrieve the stored salt for that user
2. Hash the submitted password with the same salt and parameters
3. Compare the result against the stored hash (constant-time comparison)
The salt must be stored alongside the hash; you cannot verify a login without the original salt. Storing salts in plaintext is correct and expected — their protection comes from uniqueness and size, not secrecy.
Choosing a hashing algorithm
The salt generator pairs with any KDF, but the choice of algorithm matters more than salt size:
| Algorithm | Status | Notes |
|---|---|---|
| Argon2id | Recommended | Winner of PHC; memory-hard, GPU-resistant |
| bcrypt | Still acceptable | Work factor should be 12+ in 2024 |
| scrypt | Acceptable | Memory-hard; more complex to tune |
| PBKDF2 | Legacy | Only acceptable with high iteration count (600,000+) |
| MD5 / SHA-1 / SHA-256 alone | Never use | Fast algorithms; vulnerable to GPU brute-force |
Argon2id with a 16-byte random salt is the current best practice for new systems.
Best practices
- Generate a fresh salt for every password — never reuse a single salt across users.
- 16 bytes (128 bits) is the standard minimum; larger salts are fine but rarely necessary.
- The salt is not a replacement for a slow hashing function. Always pair salting with a deliberately slow algorithm like Argon2 or bcrypt with a sufficient work factor.
- Store the salt with the hash; you need it again to verify a login attempt.
- Use constant-time comparison (e.g.,
crypto.timingSafeEqualin Node.js) when checking hashes — ordinary string comparison leaks timing information.
Everything here runs locally, so generated salts never touch a network and stay private to your machine.