Secret Key Generator
A secret key is not a credential a person presents; it is key material a program uses to sign or encrypt. Nobody types it, so the only questions are how many bits it carries and where it lives.
Match the Length to the Algorithm
| Use | Required | Notes |
|---|---|---|
| HMAC-SHA256 (JWT HS256) | ≥ 256 bits | Shorter keys are the most common JWT weakness |
| AES-128 | 128 bits exactly | |
| AES-256 | 256 bits exactly | |
Django SECRET_KEY | ≥ 50 characters | Signs sessions and CSRF tokens |
Rails secret_key_base | 128 hex characters | |
| Session cookie signing | ≥ 256 bits |
Base64url for Environment Files
A key going into an .env file or a container secret should avoid characters that need
quoting or escaping. Base64url — A–Z, a–z, 0–9, -, _ — is safe in a shell, a
YAML file and a Docker environment variable without any quoting.
Hex is equally safe and 33% longer for the same entropy.
Where a Secret Must Not Live
- Source control. Once committed it is in the history forever; rotating is the only fix,
- Client-side code. Anything shipped to a browser or a mobile binary is public.
- Build logs and CI output, which are often readable more widely than the repository.
- Error reports, where environment dumps routinely include every variable.
Rotation
Support two valid keys at once — verify against both, sign with the new one — or rotation means downtime and therefore never happens. For signing keys, a key id in the message header makes this straightforward.
Per-Environment Keys
Development, staging and production must have different secrets. Sharing one means a developer laptop compromise is a production compromise, and it makes the blast radius of any leak the whole estate.
The Avalanche Effect
A one-character change produces a completely different digest — not a similar one. That property is what makes a hash useful as a fingerprint:
| Input | MD5 | CRC32 |
|---|---|---|
hello | 5d41402abc4b2a76b9719d911017c592 | 3610a686 |
hello. | d94c10e437d18531e122ed0b45badd2a | 0a39d4f1 |
Hello | 8b1a9953c4611296a827abf8c47804d7 | f7d18982 |
hello and Hello differ by one bit of one byte, and share no part of their output.
RIPEMD-160 of hello is 108f07b8382412612c048d07d13f814118445acd, and of Hello is
d44426aca8ae0a69cdbc4021c64fa5ad68ca32fe — same story.Digest Length and Collision Resistance
| Algorithm | Output | Birthday bound | Status |
|---|---|---|---|
| CRC32 | 32 bits | ~77,000 values | Checksum only |
| MD5 | 128 bits | 2⁶⁴ in theory | Broken — collisions in seconds |
| SHA-1 | 160 bits | 2⁸⁰ in theory | Broken — SHAttered, 2017 |
| RIPEMD-160 | 160 bits | 2⁸⁰ | No practical attack |
| SHA-256 | 256 bits | 2¹²⁸ | Current standard |
| SHA-512 | 512 bits | 2²⁵⁶ | Standard, faster on 64-bit |
Never Hash a Password With These
A general-purpose hash is designed to be fast, which is exactly wrong for passwords: speed helps the attacker. Use a deliberately slow KDF — bcrypt, scrypt or Argon2id — with a per-password salt. A GPU tries billions of SHA-256 guesses a second and a few thousand bcrypt guesses a second, and that gap is the entire defence.