Salt Generator
Generate a random salt for password hashing as hex, Base64 or plain letters and numbers. Make one or a thousand, or get a fresh set of WordPress keys and salts for wp-config.php. Everything runs in your browser.
16 random bytes → f9f36928cd7d56d8f7d890d99e62f22a
Size
Format
Salt
32 characters · 128 random bits
Fine-tune
Made in your browser with its secure random generator. Nothing is sent to a server or saved.
How to generate a salt
- Pick a size. 16 bytes (128 bits) is the usual choice and is already selected.
- Pick the format your code or config file expects: Hex, Base64, URL-safe Base64, or Letters & numbers if symbols cause trouble.
- Copy the salt. Click New salt for another. To make many at once, set How many under Fine-tune and download them as a text file.
A salt is a random value that is mixed into a password before it is hashed. It is stored next to the hash, in plain sight, and its only job is to be different for every password. Each salt here comes from your browser's cryptographically secure random generator, the same source it uses for encryption keys.
Worked example: two people, one password
Two people sign up to the same site and both choose the password sunshine. Here is what ends up in the database with and without a salt.
Without a salt: plain SHA-256
Person A → a941a4c4fd0c01cd…
Person B → a941a4c4fd0c01cd…
The hashes are identical, so anyone who sees the database knows they share a password. And because sunshine is a common password, its hash is already in the precomputed lookup lists (rainbow tables) attackers use.
With a random 16-byte salt each: PBKDF2-SHA256, 600,000 iterations
Person A · salt 9c1185a5c5e9fc54… → 80118903…
Person B · salt e3b7d04c2a91f65e… → 30ad68bc…
Same password, completely different hashes. Lookup lists are useless, and an attacker has to guess each person's password separately. To log someone in, the site reads their salt from the database, hashes the typed password with it, and compares. You can repeat this example in the PBKDF2 Generator.
How long should a salt be?
16 bytes (128 bits) is the standard answer. It is what bcrypt uses, what the Argon2 standard recommends, and the minimum NIST sets for PBKDF2. At that size, two people getting the same salt by chance is practically impossible. A longer salt does no harm, but it does not make the password any harder to crack.
| Size | Bits | Hex characters | Base64 characters | When to use it |
|---|---|---|---|---|
| 8 bytes | 64 | 16 | 12 | Older systems that ask for it. Above NIST's 32-bit minimum. |
| 16 bytes | 128 | 32 | 24 | The default for passwords: PBKDF2, bcrypt, scrypt, Argon2. |
| 32 bytes | 256 | 64 | 44 | When a system asks for it, or for HKDF with SHA-256. |
| 64 bytes | 512 | 128 | 88 | Rarely needed. HKDF with SHA-512. |
Watch the units. A setting that says “salt length 16” usually means 16 bytes, which is 32 hex characters, not 16 characters. If a system asks for a salt as text of a certain length, use Letters & numbers: 22 of them carry about the same randomness as 16 bytes.
Hex, Base64 or letters and numbers?
Hex, Base64 and URL-safe Base64 are three ways of writing the same random bytes as text. Pick whichever your code or config file expects. Here is one 16-byte salt in each:
| Format | The salt | Length |
|---|---|---|
| Hex | 9c1185a5c5e9fc54612808977ee8f548 | 32 |
| Base64 | nBGFpcXp/FRhKAiXfuj1SA== | 24 |
| URL-safe | nBGFpcXp_FRhKAiXfuj1SA | 22 |
- Hex is the safest to paste anywhere: only
0–9anda–f. - Base64 is shorter, but contains
+,/and=, which can break URLs, file names and some config formats. - URL-safe uses
-and_instead and drops the=, so it is safe in URLs and.envfiles. - Letters & numbers is a random string rather than encoded bytes, for systems that take the salt as plain text.
One thing to get right: if your code decodes the salt (from hex or Base64) before hashing, the result is different from using the same characters as text. Both are fine as long as you do it the same way every time.
Do you need a salt with bcrypt or Argon2?
No. bcrypt, scrypt and Argon2 libraries create a random salt for every password and store it inside the hash string they return. A bcrypt hash like $2b$12$R9h/cIPz0gi.URNNX3kh2O… already holds its 16-byte salt (the 22 characters after the cost). Let the library do it; don't pass your own salt unless you have a specific reason.
A separate salt is what you need for:
- PBKDF2, where your code usually supplies the salt and stores it alongside the hash.
- Deriving an encryption key from a password, where the salt is saved with the encrypted data.
- HKDF and other key derivation, test data, and config files that ask for a random salt value.
Never store passwords as a plain salted hash such as SHA-256 of salt plus password. A salt stops lookup lists, but a fast hash still lets an attacker test billions of guesses a second. Use a slow password hash (Argon2id, scrypt, bcrypt or PBKDF2) and give it the salt.
WordPress salt keys
WordPress uses eight random values in wp-config.php (four keys and four salts) to secure login cookies. The WordPress keys tab makes a fresh set in the same format as WordPress's own generator: 64 random characters each, never containing a quote or backslash that could break the file.
- Open
wp-config.phpin your site's root folder, using your host's file manager or SFTP. - Find the eight
definelines forAUTH_KEYthroughNONCE_SALT. They may have placeholder text or older random values. - Replace them with the eight lines from the tool and save the file.
Everyone who is logged in, including you, is signed out and has to log in again. That is the point: changing the salts after a suspected break-in invalidates any stolen login cookies. Passwords are not affected.
Generate a salt in code or the terminal
In an app, generate a new salt for each password when it is set, using your language's secure random source. Each of these makes 16 random bytes:
Terminal (OpenSSL)
openssl rand -hex 16
Python
import secrets salt = secrets.token_hex(16)
Node.js
const salt = require('crypto').randomBytes(16).toString('hex');Browser JavaScript
const salt = crypto.getRandomValues(new Uint8Array(16));
PHP
$salt = bin2hex(random_bytes(16));
C# (.NET 6+)
using System.Security.Cryptography; var salt = RandomNumberGenerator.GetBytes(16);
Avoid Math.random(), rand(), timestamps or user IDs as salts. They are predictable or repeat, which defeats the purpose.
Frequently asked questions
Does a salt need to be kept secret?
No. A salt is stored in plain text right next to the hash, because the site needs it to check the password at login. Its job is to be unique, not secret. A secret value added to every password is called a pepper, and it is kept outside the database.
Can I use the same salt for every password?
No. One shared salt means two people with the same password still get the same hash, and an attacker can build a single lookup list for your whole database. Every password needs its own salt, and it should change whenever the password changes.
What is the difference between a salt and a pepper?
A salt is random, different for every password, and stored with the hash. A pepper is one secret value shared by all passwords and kept somewhere else, such as an environment variable or a key vault, so a stolen database alone is not enough to start guessing.
Is a salt the same as an IV or nonce?
They are all random values that are not secret, but they belong to different jobs. A salt goes into password hashing or key derivation. An IV or nonce goes into encryption, and its size is set by the cipher: 12 bytes for AES-GCM and 16 bytes for AES-CBC.
Are these salts safe to use?
Yes. They come from crypto.getRandomValues, the browser's cryptographically secure generator, and are made on your device without being sent anywhere. For salts your app stores, it is still simpler to generate them in code at the moment each password is set.
Sources
- OWASP Password Storage Cheat Sheet: salting, peppering, and which password hashes to use
- NIST SP 800-63B, Digital Identity Guidelines: stored passwords must be salted with at least 32 bits
- NIST SP 800-132, Password-Based Key Derivation: PBKDF2 salts of at least 128 random bits
- RFC 9106, Argon2: a 16-byte salt recommended for password hashing
- WordPress: editing wp-config.php: what the security keys and salts do
- MDN: Crypto.getRandomValues(): the secure random source used here
Related Tools
PBKDF2 and key derivation functions.
SHA-1 hashes of text or files, and Git object IDs.
SHA-256, SHA-384 and SHA-512 hashes of text or files.
Break secrets into verifiable shares.