How to generate a key
- Click the preset that matches what you are configuring. 32 bytes is selected when the page opens.
- Copy the value from Random values. Presets with a config line, such as Laravel or Auth.js, also show it under Ready to paste.
- Press Generate new for another key, or raise How many to create several at once, for example one per environment.
Presets set the byte count and format for you. Change either field and the tool switches back to Custom, keeping your values.
Presets and where each key goes
| Preset | What you get | Length | Typical place |
|---|---|---|---|
| 16 / 32 / 64 bytes | random bytes as Base64 | 24 / 44 / 88 | generic keys, salts, secrets |
| Laravel APP_KEY | base64: + 32 bytes | 51 | APP_KEY in .env |
| AES-128 key | 16 bytes, Base64 | 24 | AES-128-GCM or -CBC |
| AES-256 key | 32 bytes, Base64 | 44 | AES-256-GCM or -CBC |
| HMAC secret | 32 bytes, Base64 | 44 | HMAC-SHA256 signing, webhooks |
| JWT HS256 secret | 32 bytes, Base64URL | 43 | JWT_SECRET for HS256 tokens |
| Auth.js secret | 32 bytes, Base64 | 44 | AUTH_SECRET (formerly NEXTAUTH_SECRET) |
| Django SECRET_KEY | 50 characters from Django’s alphabet | 50 | SECRET_KEY in settings |
| Rails secret_key_base | 64 bytes, hex | 128 | secret_key_base |
| API token | 32 bytes, Base64URL | 43 | bearer tokens, invite links |
| UUID v4 (Base64URL) | a random UUID in short form | 22 | compact IDs; the canonical UUID is shown too |
The CSP nonce preset belongs to a different job; it has its own page, the CSP nonce generator.
The sizes follow the algorithms. AES keys are exactly 16, 24 or 32 bytes; anything else is rejected. RFC 7518 requires HS256 secrets of at least 256 bits, which is why the JWT preset uses 32 bytes. An HMAC key shorter than the hash output weakens HMAC, so 32 bytes suits HMAC-SHA256 and the 64-byte preset suits HMAC-SHA512. The Django preset draws its 50 characters by rejection sampling, so every character of the alphabet is equally likely, the same way Django’s own get_random_secret_key() behaves.
A Base64 key is text, the key is bytes
The value you copy is a Base64 representation of random bytes. Code that uses it must decode it first:
import base64, os
key = base64.b64decode(os.environ["AES_KEY"])
assert len(key) == 32
In Node.js the same is Buffer.from(process.env.AES_KEY, "base64"). If you hand the 44-character string straight to an AES library, it either rejects it (AESGCM key must be 128, 192, or 256 bits in Python, Invalid key length in Node.js) or, in looser libraries, uses the wrong bytes without complaint. Frameworks that read their own keys, such as Laravel with its base64: prefix, do this decoding for you.
Base64URL and standard Base64 decode to the same bytes, but parsers are often strict about which one they accept. Keep the format the preset produced unless you know the consumer accepts the other.
Fernet keys and other formats
Python’s cryptography package expects a Fernet key as 32 bytes in URL-safe Base64 with padding, 44 characters. The JWT and API token presets give the URL-safe form without the =, so add one at the end, or generate it in Python:
from cryptography.fernet import Fernet
print(Fernet.generate_key().decode())
For anything else, work from the byte count: pick Custom, enter the bytes your library documents, and choose Base64, Base64URL or hex. The random Base64 generator explains output lengths, and HMAC in Base64 or AES encryption let you try a fresh key straight away.
Handling keys after generating them
A key generated here exists only in this tab until you copy it. After that it is as safe as the place you paste it into. Keep production keys in your platform’s secret store or a secrets manager, use a different key per environment, and never commit them; a key that reached a Git repository should be considered public and replaced. Rotating an encryption key means re-encrypting old data or keeping the old key for decryption, so plan for that before you swap an APP_KEY on a live system.
FAQ
How do I generate a 32-byte Base64 key?
The 32 bytes preset is selected when the page opens, so the key in the output is already one: 44 characters ending in =. In a terminal, openssl rand -base64 32 does the same.
Can I use the 44-character Base64 string directly as an AES-256 key?
No. AES-256 needs 32 raw bytes, and the 44 characters are their Base64 text. Decode the string first; passing the text itself fails with an error such as “Invalid key length” in Node.js.
How do I generate a Laravel APP_KEY without artisan?
Choose the Laravel APP_KEY preset and copy the APP_KEY=base64:… line into .env. It has the same format php artisan key:generate writes: the base64: prefix plus 32 random bytes for the default AES-256-CBC cipher.
How do I make a Fernet key here?
There is no Fernet preset. Choose 32 bytes, set Format to Base64URL and add one = to the 43 characters, because Fernet expects padded URL-safe Base64 of 44 characters. Or run Fernet.generate_key() in Python.
Is it safe to generate production keys in a browser?
The key comes from crypto.getRandomValues, a cryptographically secure generator, and the page cannot send it anywhere. The bigger risk is what happens next: put the key in a secrets manager or a protected environment variable, never in a repository.