3tej home

Strong Password Generator

Make secure passwords using your browser's cryptographic randomness.

Pick a length and character classes. The generator uses crypto.getRandomValues for unbiased selection.

Generated password
-
Character pool size-
Entropy-
Strength-
How is this calculated?

Each character is picked uniformly from the chosen pool using crypto.getRandomValues with rejection sampling to avoid modulo bias. Entropy = length x log2(pool_size) bits. NIST SP 800-63B treats memorized secrets above about 80 bits as strong for most uses. Symbols come from !@#$%^&*()-_=+[]{}|;:,.<>?/~. Source: NIST SP 800-63B Digital Identity Guidelines.

About the strong password generator

The strong password generator produces cryptographically random passwords of 8 to 64 characters using the browser's Web Crypto API. Output is generated in your browser; nothing leaves the page. Each character is selected uniformly from a pool of lowercase, uppercase, digits, and symbols, with optional exclusion of visually ambiguous characters (O 0 l 1 I). The result is an unbiased, high-entropy secret suitable for any account that cares about brute-force resistance.

How it works

The algorithm has three steps. (1) Build the character pool by concatenating the selected character classes and de-duplicating. (2) For each output position, draw a uniformly random index into the pool using crypto.getRandomValues with rejection sampling to avoid modulo bias. (3) Concatenate the characters and report the entropy as length x log2(pool_size).

// Pseudocode
pool = build_pool(selected_classes)         // e.g. 94 characters
length = clamp(user_length, 8, 64)

password = ""
for i in 0..length-1:
  password += pool[secure_index(pool.length)]

secure_index(n):
  limit = floor(2^32 / n) * n             // largest multiple of n below 2^32
  loop:
    x = crypto.getRandomValues(Uint32)[0] // 32-bit unbiased random
    if x < limit: return x mod n           // rejection sampling

entropy = length * log2(pool.length)        // in bits

The Web Crypto API's getRandomValues is backed by the operating system's secure random source. On Linux this is /dev/urandom seeded from hardware noise; on Windows it is BCryptGenRandom (CTR_DRBG per NIST SP 800-90A); on macOS it is SecRandomCopyBytes (CTR_DRBG seeded from the kernel's entropy pool). All three meet the FIPS 140-2 random number generator requirements.

Worked example

Generate a 16-character password with all four character classes enabled and ambiguous characters excluded:

  1. Pool construction: 26 lowercase + 26 uppercase + 10 digits + 28 symbols = 90 characters. Remove ambiguous (O, 0, l, 1, I): 90 - 5 = 85 characters.
  2. Entropy per character: log2(85) = 6.41 bits.
  3. Total entropy: 16 x 6.41 = 102.6 bits.
  4. For each of 16 positions, draw a Uint32 from crypto.getRandomValues, reject any value above floor(2^32 / 85) x 85 = 4,294,967,295 - 80 = 4,294,967,215, then pick pool[x mod 85].
  5. Concatenate. Example output (single run): Hr5tQzK@9wEbA#Pm
Result: 102.6 bits of entropy is in the "Very strong" tier. An attacker brute-forcing offline at 1 trillion guesses per second (high-end GPU farm) needs 2^102.6 / 10^12 / 60 / 60 / 24 / 365 = roughly 2.5 x 10^11 years to enumerate the space. Heat death of the sun is in about 5 billion years. The password is safe.

Password entropy reference

Entropy scales linearly with length and logarithmically with pool size. The table below shows entropy in bits for common configurations.

LengthDigits only (10)Lowercase (26)Lower+Upper (52)Lower+Upper+Digit (62)All printable ASCII (94)
826.637.645.647.652.4
1239.956.468.471.578.7
1653.275.291.295.3104.9
2066.494.0114.0119.1131.1
32106.3150.4182.4190.6209.8
64212.6300.8364.8381.1419.6

Threshold guide: below 40 bits is weak (cracked in minutes by a botnet); 40 to 60 is reasonable for low-value accounts; 60 to 80 is strong for online accounts (rate-limited login); 80 to 128 is overkill for online but baseline for offline-attack resistance; 128+ is excessive but harmless.

Common pitfalls and limitations

  • Modulo bias in naive PRNG code. A common mistake is array[crypto.getRandomValues(Uint32)[0] % n]. If n does not divide 2^32 evenly, some indices are picked slightly more often than others. The generator uses rejection sampling to eliminate the bias; if you adapt this code elsewhere, copy the rejection loop too.
  • Web Crypto availability. crypto.getRandomValues is available in all browsers from 2014 onwards. On extremely old browsers (IE 10 and earlier) or offline mobile WebViews with crippled CSP, the API returns undefined; the generator falls back to printing an error rather than silently using Math.random.
  • Site-imposed limits. Many sites cap password length at 16 or 32 characters and reject certain symbols (commonly $, %, &, <, >, '). A 64-character password may be silently truncated on input, defeating the entropy gain. Check the site's password policy before generating; pick a length and class set that fit.
  • Memorability vs entropy. Humans cannot remember a 20-character random string. NIST SP 800-63B explicitly recommends password managers for any account that needs unique high-entropy secrets. Memorable passwords plateau around 40 to 50 bits because real-world humans pick from a much smaller subset of all possible strings.
  • Symbol set assumptions. The generator uses 28 symbols from !@#$%^&*()-_=+[]{}|;:,.<>?/~. Some legacy systems treat $, %, and ! as shell metacharacters, breaking authentication or password reset. If a site requires special characters but accepts only a narrow set, deselect symbols and use length to compensate.
  • Copy-paste through clipboard managers. Cloud clipboard managers (Microsoft's clipboard history, macOS Universal Clipboard, Android's Gboard clipboard) may sync the password to the cloud. Disable clipboard sync before generating, or paste the password directly into your manager and clear the clipboard.

Frequently asked questions

What is password entropy and how much do I need?

Entropy measures how unpredictable a password is, in bits. Each bit doubles the number of possible passwords. NIST SP 800-63B treats memorized secrets above roughly 80 bits as strong for most online accounts; 128+ bits is overkill but harmless. A 20-character random password drawn from the 94-character printable ASCII set has length x log2(94) = 20 x 6.55 = 131 bits, well past any practical brute-force threshold.

Why does this generator use Web Crypto API instead of Math.random?

Math.random() is a pseudorandom generator (PRNG) seeded from the page load time. Its output is fast but predictable: an attacker who knows roughly when the page loaded can reconstruct the password. crypto.getRandomValues uses the operating system's cryptographically secure random source (CryptGenRandom on Windows, /dev/urandom on Linux, SecRandomCopyBytes on macOS), seeded from hardware entropy. RFC 4086 requires this kind of source for any cryptographic secret.

What is rejection sampling and why does the generator use it?

To pick uniformly from a pool of N characters using a 32-bit random value, naive code does random % N. This introduces modulo bias: if N does not divide 2^32 evenly, some indices are picked slightly more often than others. Rejection sampling discards any random value above the largest multiple of N that fits in 32 bits, eliminating the bias. The cost is that roughly 1 in (2^32 / floor(2^32/N) x N) values are discarded, which is negligible for N below 256.

Should I store this password in my head, in a password manager, or written down?

Password manager. NIST SP 800-63B explicitly recommends managers (1Password, Bitwarden, KeePassXC, Apple Passwords, Chrome built-in) because human-memorable passwords always have less than 50 bits of entropy. A written-down 20-character random password in a locked drawer at home is acceptable for very high-value accounts (master password, banking) but not for the dozens of low-value accounts most people accumulate.

Sources and further reading

Last updated 2026-05-28.