Entropy (Cryptographic)
In cryptography, entropy measures the unpredictability of a random value. High entropy means an attacker cannot guess or predict the value. Cryptographic keys, IVs, salts, and CSRF tokens must be generated from a cryptographically secure pseudo-random number generator (CSPRNG) with sufficient entropy.
In cryptography, entropy measures how unpredictable or random a value is, expressed in bits. A string with N bits of entropy requires on average 2^(N-1) guesses to find by brute force. Entropy is the foundation of cryptographic security — weak entropy leads to predictable keys, tokens, and salts that can be guessed or brute-forced.
Calculating Password Entropy
Password entropy is approximately:
Entropy (bits) = log2(character_set_size ^ password_length)
= password_length × log2(character_set_size)
| Character Set | Size | Bits/Char | 12 chars |
|---|---|---|---|
| Digits only | 10 | 3.32 | ~40 bits |
| Lowercase | 26 | 4.70 | ~56 bits |
| Mixed case | 52 | 5.70 | ~68 bits |
| Alphanumeric | 62 | 5.95 | ~71 bits |
| Alphanumeric + symbols | 94 | 6.55 | ~79 bits |
| Passphrase (5 words from 7776-word list) | — | — | ~65 bits |
For web authentication, 64 bits of entropy is a practical minimum. For tokens and API keys, use at least 128 bits.
Entropy Sources
Cryptographically Secure Random Number Generators (CSPRNG)
// Browser / Node.js — always use this for security
const bytes = crypto.getRandomValues(new Uint8Array(32)); // 256 bits
// Node.js crypto module
import { randomBytes } from "crypto";
const token = randomBytes(32).toString("hex"); // 256-bit hex token
import secrets
# Cryptographically secure random bytes
token_bytes = secrets.token_bytes(32) # 256 bits
token_hex = secrets.token_hex(32) # 256-bit hex string
token_url = secrets.token_urlsafe(32) # URL-safe Base64
# Secure random integer
pin = secrets.randbelow(1000000) # 6-digit PIN
Not Cryptographically Secure
// WRONG — Math.random() is not a CSPRNG
const badToken = Math.random().toString(36); // predictable, never for security
// WRONG — Timestamp is not random
const badId = Date.now().toString(); // guessable
Token Length Recommendations
| Purpose | Entropy | Token Length |
|---|---|---|
| Session ID | 128 bits | 16 bytes → 32 hex chars |
| Password reset link | 128 bits | 16 bytes → ~22 Base64 chars |
| API key | 256 bits | 32 bytes → 64 hex chars |
| CSRF token | 128 bits | 16 bytes → 32 hex chars |
| OAuth authorization code | 128 bits | 16 bytes |
| Email verification token | 128 bits | 16 bytes |
Entropy and UUIDs
UUID v4 contains 122 bits of entropy — sufficient for distributed unique identifiers. UUID v4 is not suitable for security tokens where unpredictability is critical and collision probability of 1 in 2^122 is not the same constraint as cryptographic unpredictability.
For security tokens, use crypto.randomBytes(32) or crypto.randomUUID() (which uses CSPRNG internally) rather than UUID libraries that might use Math.random().
Low Entropy Vulnerabilities
- Predictable session IDs: PHP's early
rand()-based session IDs were guessable - Time-seeded PRNGs:
srand(time())gives attackers a small search space - Short tokens: 6-digit numeric tokens (20 bits) are brute-forceable in minutes
- Truncated UUIDs: using only the first 8 characters of a UUID dramatically reduces entropy
Always audit entropy sources in security-critical code paths.