Encryption Key Generator

Generate cryptographically-strong app secrets, API keys, AES/HMAC keys, UUIDs, and OTP codes. Runs in your browser.

Runs entirely in your browser. Nothing is sent to our servers.

Generate multiple at once (e.g. for multiple environments).
Click Generate.
This runs entirely in your browser. Keys are generated using crypto.getRandomValues() — the browser's cryptographically-strong random number generator. Nothing is sent to any server. But: once you see a key, treat it like a password. Don't paste it into chat, don't commit it to a repo, and rotate it immediately if it ever leaks.

About this tool

Generates cryptographically-strong random keys for various purposes — application secrets, JWT signing keys, AES encryption keys, OTP codes, UUIDs. Uses your browser's built-in crypto.getRandomValues(), which is the same source that HTTPS, key generation, and other security-sensitive operations use.

Which one do I want?

For app secrets — things like APP_KEY in Laravel, SECRET_KEY in Django, JWT signing secrets, session secrets, API keys for your own services — use one of the ASCII random strings. 32 characters is the conventional floor; 64 is the comfortable default; longer doesn't really add security past 256 bits of entropy.

For actual cryptography — AES-256 encryption keys, HMAC signing keys, anything where the spec says "N-bit key" — use the raw-bytes variants. The "256-bit key, hex" output is 32 bytes of randomness displayed as 64 hex characters; that's what AES-256 wants. Base64 encoding is more compact (44 chars for 32 bytes), and base64url is the URL-safe variant.

UUIDs are for identifiers, not secrets — they're not random enough to use as authentication keys. Use them when you need a unique-but-non-secret identifier (database row IDs, request tracing).

What "cryptographically-strong" actually means

Standard Math.random() is fast but predictable — given enough output, you can predict the next number. That's catastrophic for keys. crypto.getRandomValues() draws from the operating system's entropy pool (hardware noise, mouse movements, network timing) and is suitable for cryptographic use. This tool uses the latter exclusively.

Storing keys safely

  • Never commit keys to git. Use .env files and .gitignore them.
  • Use different keys per environment (dev, staging, production).
  • Rotate keys periodically and immediately on any suspected exposure.
  • Don't email keys. Use a password manager for sharing (1Password, Bitwarden, etc.) or a one-time-share service.
  • For server-side use, consider a secrets manager (AWS Secrets Manager, HashiCorp Vault) instead of plain .env files.

Frequently asked questions

What's the difference between a 32-character string and a 32-byte key?
A 32-character string is 32 ASCII characters — depending on the alphabet used, that's about 190 bits of entropy (with a 62-char alphabet of A-Za-z0-9). A 32-byte key is 32 raw bytes = exactly 256 bits of entropy. For app secrets, the 32-char string is more than enough. For AES-256, you need actual 32 bytes (typically displayed as 64 hex chars or 44 base64 chars).
Is this safe to use for production keys?
Yes — but with a caveat. The randomness is cryptographically strong, so the keys themselves are safe. The risk is the environment: if your machine has malware that's watching what you type or paste, that's a problem regardless of where you got the key. For ultra-sensitive production keys, generate them directly on the production server with openssl rand or similar.
Should I use the UUID for authentication tokens?
No. UUIDs have predictable structure (version 4 has 122 random bits but is recognizable as a UUID), and they're commonly used as non-secret identifiers — so attackers may probe them. Use one of the random-string or random-bytes options for tokens; reserve UUIDs for IDs.
Why is the OTP code only 6-8 digits?
OTPs (one-time passwords) need to be short enough for humans to type. They're only safe if used once and rate-limited (e.g. lock account after 5 wrong attempts). 6 digits = 1 in a million chance per guess, which is safe with rate limiting. Don't use these as permanent passwords.
Can I trust crypto.getRandomValues() in older browsers?
It's been universally supported since 2014 (IE 11, all evergreens). The tool will refuse to generate keys if the API isn't available — that should never happen on a modern browser, but if it does, don't fall back to Math.random(); use a different tool.

Last updated: May 21, 2026