Secret Key Generator for API Keys and JWT Secrets
Generate cryptographically random secret keys in hex, base64, base64url or alphanumeric
2 characters per byte — safe everywhere
Entropy: 0 bits per key
Generated in your browser with crypto.getRandomValues; nothing is sent anywhere. Need something a human types? Use the password generator. Inspect a token signed with your new secret in the JWT decoder, or generate identifiers (not secrets) with the UUID generator.
What the secret key generator is for
Applications are full of values that must simply be unguessable: the HMAC secret that signs your JWTs, a session or cookie signing key, a webhook signing secret, Django's SECRET_KEY, Rails' secret_key_base, an encryption key for a field-level cipher, or the API keys you issue to your own customers. All of them are just random bytes, and the only property that matters is that they come from a cryptographically secure random number generator and are long enough.
This tool draws bytes from crypto.getRandomValues, the browser's CSPRNG, which is seeded by the operating system — the same source as /dev/urandom or Python's secrets module. Keys are generated locally and never sent anywhere, and the page deliberately has no share link because the output is a secret.
Choosing a length and a format
Length is measured in random bytes, and every byte is 8 bits of entropy. 16 bytes (128 bits) is the floor for anything security-relevant and is already far beyond brute force. 32 bytes (256 bits) is the sensible default and matches the key size of HS256 — RFC 7518 requires an HMAC key at least as long as the hash output, so 32 bytes for HS256, 48 for HS384 and 64 for HS512. Use 64 bytes when a framework asks for it or for HS512.
The format only changes how the bytes are written down, not how strong they are. Hex uses two characters per byte and is safe in any config file or shell. Base64 is about a third shorter but contains +, / and =, which need escaping in URLs. Base64url swaps those for - and _ and drops the padding, so it is safe in URLs, HTTP headers and file names. Alphanumeric uses only A–Z, a–z and 0–9 for systems that reject symbols; it is built by rejection sampling — random bytes outside an exact multiple of 62 are discarded — so every character is equally likely, and its length is chosen to carry at least the same entropy as the selected byte count (43 characters for 256 bits). Django SECRET_KEY produces 50 characters from the same alphabet Django's get_random_secret_key() uses, roughly 282 bits.
The entropy shown is the exact number of random bits in each key. A prefix adds none.
Prefixes, bulk keys and handling secrets
A short prefix such as sk_live_ or myapp_test_ makes keys self-describing: you can tell environment and purpose at a glance, route support tickets, and let secret scanners such as GitHub's push protection recognise leaked keys by pattern. Bulk mode generates up to 100 independent keys at once, for seeding test fixtures or issuing a batch of tokens.
Once generated, store secrets in environment variables or a secrets manager rather than in source code, rotate them when people leave or a leak is suspected, and store only a hash of customer API keys server-side, as you would a password. For anything a human must type or remember, use a password generator instead; for identifiers that only need to be unique rather than secret, a UUID is enough.
How to use the Secret Key Generator for API Keys and JWT Secrets tool
- 1
Pick a format
Choose hex, base64, base64url, alphanumeric or the Django SECRET_KEY preset.
- 2
Set the length
Use 16, 32 or 64 random bytes, or type a custom length; the entropy in bits is shown below.
- 3
Add a prefix or batch size
Optionally add a prefix like sk_live_ and choose how many keys to generate, up to 100.
- 4
Copy and store securely
Copy one key or all of them into your environment variables or secrets manager. Nothing is saved by the page.
Frequently asked questions
Are the keys generated securely?
Yes. They come from crypto.getRandomValues, the browser's cryptographically secure random number generator, and are created locally. Nothing is sent to a server or stored.
How long should a JWT secret be?
At least as long as the hash: 32 random bytes (256 bits) for HS256, 48 for HS384 and 64 for HS512, as RFC 7518 requires. Shorter secrets can be brute-forced offline from any token.
What is the difference between base64 and base64url?
They encode the same bytes. Base64url replaces + and / with - and _ and drops the = padding, so the key can go in URLs, headers and filenames without escaping.
Is alphanumeric output weaker than hex?
Not here. Each alphanumeric character carries about 5.95 bits, and the length is chosen so the key has at least the selected entropy; rejection sampling keeps every character equally likely.
Can I use this for a Django SECRET_KEY?
Yes. The Django preset produces a 50-character key from the same character set Django's get_random_secret_key() uses. Put it in an environment variable rather than settings.py.
Related on TechLogHub
Related Security Tools
UUID Generator for v4 and v7 with Bulk Output
Generate v4 and v7 UUIDs in bulk and inspect any UUID or GUID
Hash Generator: MD5, SHA-256, SHA-512 and HMAC
Compute MD5, SHA-1, SHA-256, SHA-384 and SHA-512 hashes and HMACs of text or files
Bcrypt Hash Generator and Verifier with Cost
Hash passwords with bcrypt at a chosen cost factor and verify passwords against bcrypt hashes
Password Generator with Passphrases and Entropy
Generate strong random passwords or word-based passphrases with an entropy meter
SSH Keygen Online for Ed25519 and RSA 4096 Keys
Generate Ed25519 or RSA SSH key pairs in OpenSSH format, locally in your browser
TOTP Generator with Countdown and otpauth URIs
Compute RFC 6238 TOTP codes from a base32 secret and build otpauth:// URIs for testing 2FA
Get the next tool before you need it
One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.

