Math.random() Is Not Secure
Math.random() uses a pseudorandom number generator (PRNG) — an algorithm that produces a deterministic sequence from a seed. While the output looks random, a PRNG with a known or guessable seed can be predicted. In V8 (Node.js/Chrome's JS engine), Math.random() uses xorshift128+, which has been shown to be predictable from its output. Do not use it for security-sensitive applications.
crypto.getRandomValues() — The Secure Alternative
The Web Crypto API's crypto.getRandomValues() uses the operating system's entropy source (hardware events, interrupt timing, etc.) — an unpredictable source suitable for cryptographic purposes. Available in all modern browsers and Node.js (via globalThis.crypto).
// Generate 16 random bytes
const array = new Uint8Array(16);
crypto.getRandomValues(array);
// Random integer in [min, max)
function randomInt(min, max) {
const range = max - min;
const bytes = new Uint32Array(1);
crypto.getRandomValues(bytes);
return min + (bytes[0] % range);
}
Building a Password Generator
function generatePassword(length = 16, options = {}) {
const { upper = true, lower = true, digits = true, symbols = true } = options;
let chars = "";
if (upper) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (lower) chars += "abcdefghijklmnopqrstuvwxyz";
if (digits) chars += "0123456789";
if (symbols) chars += "!@#$%^&*()_+-=[]{}|;:,.<>?";
const bytes = new Uint32Array(length);
crypto.getRandomValues(bytes);
return Array.from(bytes, b => chars[b % chars.length]).join("");
}
Note: b % chars.length introduces a tiny bias if chars.length doesn't evenly divide 2³². For most purposes this is negligible, but for highest security use rejection sampling.
Password Entropy
Entropy measures the unpredictability of a password in bits. Higher entropy = harder to brute-force:
entropy = log2(charsetSize ^ length) = length × log2(charsetSize)
| Charset | Size | 16 chars | 20 chars |
|---|---|---|---|
| Lowercase only | 26 | 75 bits | 94 bits |
| Lowercase + digits | 36 | 83 bits | 103 bits |
| Mixed + digits | 62 | 95 bits | 119 bits |
| Full ASCII printable | 94 | 105 bits | 131 bits |
Recommendation: aim for 80+ bits of entropy for regular accounts, 128+ bits for master passwords and encryption keys.
Passphrases vs Random Passwords
A passphrase like "correct horse battery staple" (from Diceware, 4 random words from a 7776-word list) has ≈51 bits of entropy. Six words = ≈77 bits. Passphrases are memorable and can achieve high entropy, but random character passwords achieve higher entropy per character.
Password Manager Best Practices
- Use a different password for every account.
- Store passwords in a password manager (1Password, Bitwarden, etc.) — never in spreadsheets or plain text files.
- Enable two-factor authentication on your password manager and high-value accounts.
- Use 16+ character passwords for most accounts; 20+ for critical accounts.
- Include all character types unless the site explicitly forbids some.
Generate a Secure Password Now
Use ToolsVito's Password Generator — powered by crypto.getRandomValues(), runs entirely in your browser, and never transmits the generated password anywhere.