How to Generate Secure Secret Keys
A "secret key" is any value your application keeps private and uses to prove authenticity or protect data: a JWT signing secret, an encryption key, a session secret, a CSRF token, or a webhook signing key. If an attacker can guess or steal that value, every guarantee built on top of it collapses. This guide explains what actually makes a key secure and how to generate one correctly.
Two things make a key secure
It comes down to where the randomness comes from and how much of it there is.
- A cryptographically secure random source (CSPRNG). Ordinary random functions like
Math.random(),rand(), or anything seeded from the clock are predictable and must never be used for secrets. Use your platform's CSPRNG:crypto.getRandomValues()in browsers,crypto.randomBytes()in Node.js,secretsin Python, or/dev/urandomon Linux. - Enough entropy. Entropy is measured in bits and represents how many equally likely values the key could have been. Each additional bit doubles the attacker's work. A key with 256 bits of entropy cannot be brute-forced by any foreseeable technology.
How much entropy do you need?
A useful rule of thumb:
- 128 bits — the practical minimum for anything security-sensitive.
- 256 bits — the comfortable default for JWT secrets, encryption keys, and long-lived secrets.
- 384–512 bits — appropriate for HS384/HS512 JWT signing or when you simply want extra margin.
Note the difference between raw bytes and encoded length. 32 random bytes is 256 bits of entropy regardless of whether you display it as 64 hex characters or 43 Base64URL characters. The encoding changes the appearance, not the strength.
Encoding formats
The same random bytes can be represented in several ways. Pick whatever your config system handles cleanly:
- Hexadecimal — only
0–9anda–f; always safe, but the longest representation. - Base64 — compact, but contains
+,/, and=, which can be awkward in URLs or shells. - Base64URL — like Base64 but URL- and filename-safe; a great default for tokens and JWT secrets.
Common mistakes to avoid
- Reusing one secret everywhere. Each environment (dev, staging, production) and each purpose (signing, encryption, sessions) should have its own key.
- Deriving secrets from guessable inputs such as the app name, a date, or a short password.
- Committing secrets to source control. Use environment variables or a secret manager, and add secret files to
.gitignore. - Truncating a key to "make it shorter" — that throws away entropy.
Generate one now
Every value on this site is created in your browser with crypto.getRandomValues() and is never transmitted to a server. The JWT tab produces ready-to-use secrets at 16–256 bytes in your choice of format, and the Encryption and More tabs cover keys, salts, and tokens.
Ready to generate a key? Open the generator and create a 256-bit secret in any format — locally and instantly.
Open the generator