A password generator in a browser invites a reasonable doubt: where does the randomness come from, and is it rigged? The question is a fair one, and — unlike most claims about security — the answer can be checked.
Two different generators
The browser has two, and they must not be confused.
Math.random() | crypto.getRandomValues | |
|---|---|---|
| Purpose | Games, animation, shuffling a list | Secrets: passwords, keys, tokens |
| Source | An internal algorithm in the browser | The operating system's generator |
| Predictability | A few outputs reveal the rest | Cannot be reconstructed from its outputs |
| Fit for a password | No | Yes |
Where the system gets randomness
The operating system collects unpredictable events: interrupt timings, noise from devices, a hardware source in the processor. From these it maintains a pool that is constantly stirred.
The browser invents nothing of its own — it simply asks the system for the number of bytes it needs. So the quality of the generator in a browser is the quality of your operating system's generator, not a separate property of the browser.
Why a simple modulo will not do
Suppose you need a character from an alphabet of 62 and the generator returns a byte from 0 to 255. Taking the remainder modulo 62 looks sensible — but 256 does not divide evenly by 62.
In the remainder, the first few values come up four times each while the rest come up three. The early characters of the alphabet start appearing more often, and the entropy ends up lower than calculated.
The fix is called rejection: values in the leftover “tail” that does not fit a whole number of alphabet repetitions are simply discarded and a new one requested. It is slower by fractions of a microsecond, and the distribution is exactly uniform. That is how the generator on this site works.
How to check it yourself
-
Look at the page source
The scripts are not minified beyond recognition: in the generator file you can see that the system source is what gets called.
-
Open the Network tab in developer tools
Generate a password and confirm there are no requests to the server. A password cannot leak to a place it is never sent.
-
Turn off the internet and try again
The most vivid check of all: the generator keeps working. Which means everything is computed in the browser.