Skip to content

A password your browser makes on its own.

Every character comes out of your browser's cryptographic random source, the same one it uses for TLS keys. Random characters for the passwords a manager will remember for you, or diceware words for the ones you have to type yourself. There is no server on the other end of this page, so there is nothing to send the result to and nothing to keep it in.

Generated in this tab, from your browser's own randomness

Password

20 characters · 130 bits

 

Very strong

130 bits

Guessing stops being the way in at all.

The setting that decides the answer. Every extra character multiplies the number of passwords an attacker has to work through.

Characters to draw from

The symbols are !#$%&()*+,-./:;<=>?@[]^_{|}~. The quote, the double quote, the backtick and the backslash are left out: they are the four that get mangled somewhere between a shell, a CSV and a config file, and a password you cannot paste gets replaced with a worse one.

90 characters in the pool one of each guaranteed 0 network requests

Need the hash rather than the password? Hash this one with bcrypt — it is handed over in memory, never through the URL, and the hashing runs in this tab too.

Where the randomness comes from

A password generator is only as good as its source of surprise, and there are two ways to get this wrong in about the same number of lines of code.

The first is Math.random. It is a seeded generator built for shuffling animations, its output is reproducible, and its internal state can be reconstructed from a short run of the numbers it just gave you. On a page that hands out passwords, that means anyone who has one of them is a step away from the rest. This page uses crypto.getRandomValues instead, which is the browser's CSPRNG — the one behind TLS keys and session identifiers.

The second is quieter. Turning a random 32 bit number into a character with % looks harmless, but 2³² is not a multiple of 90, so the first few characters of a 90 character alphabet come up slightly more often than the rest. The fix is to throw away the values in that short tail rather than fold them back in, which costs an occasional extra draw and nothing else:

const range = 4294967296;              // 2^32
const limit = range - (range % max);   // the largest exact multiple of max
const buffer = new Uint32Array(1);

for (;;) {
  crypto.getRandomValues(buffer);
  if (buffer[0] < limit) return buffer[0] % max;
}

The "at least one from each set" option has the same shape of problem. The usual implementation plants one character from every required set and shuffles, which leaves a smaller and lumpier set of reachable passwords than the length suggests. This one draws the whole password uniformly and discards it if a set is missing, so every valid password stays exactly as likely as every other — and the bit count on the panel is the exact size of that set, worked out by inclusion–exclusion rather than rounded off.

Length is the setting that matters

With your current sets, each character is worth about 6.5 bits. The bars are drawn to scale, so the difference between 8 characters and 32 is the difference in the picture. Pick one to try it.

Words, for the ones you have to type

Some passwords never get typed by a person: they go from here into a password manager and come back out by autofill. Others you have to read off a screen, say down a phone, punch into a TV remote or remember — a disk encryption password, the master password on the manager itself, the WiFi key you give to visitors. That is the job words are for.

The method is diceware, and it is old enough to predate the web. Five dice give 7,776 outcomes, each outcome is one word on a list, and the roll is the whole of the security. This page rolls with the same crypto.getRandomValues as the character mode, on the Electronic Frontier Foundation's long wordlist — words chosen to be easy to type and hard to mishear, with no word a prefix of another. It sits in this site's repository unchanged, under CC BY 3.0 US, so you can diff it against the EFF's own copy and see that nothing was added or taken out.

The part people get wrong: every word is worth exactly 12.925 bits, whether it came out as zoo or abdominal. The attacker is not guessing letters, so a longer word is not a stronger one — it is only more to type. Assume they have the list and know the separator, because they do; the figures on this page already assume it. What you are buying is the count, and nothing else.

Repeats are allowed
Two of the same word in one phrase is not a bug. Refusing repeats would shrink the set of possible phrases, and the arithmetic on this page would stop being true.
The separator is free
Hyphen, full stop or space, it is the same for every phrase here, so it costs an attacker one guess rather than any real work. Pick whatever the box you are pasting into will take.
Capitals are free too
Capitalising every word is a fixed rule, so it adds nothing. It is here because forms ask for an uppercase, not because it helps.
The digit is not free
It is drawn one in ten, the same way as everything else, so it is worth 3.3 bits — and the entropy figure counts it.

Where words lose: length. Six words with hyphens is around 45 characters, which walks straight into forms with a 16 character maximum and into bcrypt's 72 byte limit at about ten words. If the box is small, the character mode gets more out of every character.

Two things decide whether guessing works

Cracking a leaked password is hashing candidates until one matches. How fast that runs is the site's choice of hash; how long the list of candidates is, is yours. Same attacker in every row below — one rig, eight current graphics cards — against the password on the panel above and against one a person would have come up with instead.

Stored withThis password · 130 bitsInvented · 30 bits
MD5 Salted or not, it is this fast10¹⁹ yearsinstantly
SHA-256 One round, the usual mistake10¹⁹ yearsinstantly
bcrypt at cost 12 4,096 iterations per guess10²⁷ years12 hours

The generated password holds every row, whatever the site did with it. The invented one lasts exactly as long as the hash makes it last: hours behind bcrypt, no time at all behind SHA-256. That is the whole case for generating rather than thinking of one — it takes the decision out of the hands of whoever built the login form.

And if you are the one building it, the gap in that last column is yours to pick: bcrypt or Argon2id, not SHA-256. Thirty bits is a generous estimate for a password somebody invented, the rates are order of magnitude figures rather than measurements, and both assume the average case: half the keyspace before a hit.

What this page does not do

Every item below is something you can check yourself rather than take on trust. Open the network tab and generate a hundred passwords, or turn the connection off and keep going.

No request, ever
Generating makes no network call. The page is static files that were already downloaded when it loaded, and the generator is a couple of hundred lines of JavaScript in that bundle.
Nothing kept
No cookie and no local storage at all. The only thing in session storage is the scroll position the router puts there for the back button, and nothing about the password is written anywhere. Reload the page and it is gone from everywhere except your clipboard.
Nothing in the URL
Settings and output stay out of the address bar, so nothing lands in your history or in a referrer header on the way to the next page. That is also why the link to the bcrypt tool passes the password in memory instead.
Nobody else on the page
No analytics, no tag manager, no fonts or scripts loaded from another domain. There is no third party here to measure what you generated, and no backend of ours that could receive it either.
Prerendered, not made on a server
The HTML was built once, ahead of time, with no password in it — view the source and the field is empty. The first password is made after the page loads, in your tab.

The one part outside the page's control is the clipboard. Anything running on your machine can read it until you copy something else, so paste the password where it is going and move on.

Questions people ask

Is a password generated in a web page safe to use?
It comes down to two things: where the randomness comes from, and whether the page keeps a copy. Every character here is drawn from crypto.getRandomValues, the browser's own cryptographic random source, which is the same one your TLS session keys came out of. And the site is a set of static files with no server behind it, so there is nowhere to send the result. Both are checkable rather than promises: the network tab stays empty while you generate, and the page keeps working with the connection switched off.
How many characters do I actually need?
Length is the setting that matters. With all four sets on, each character is worth about 6.5 bits, so 12 characters is around 78 bits and 20 is around 130. Past roughly 80 bits an offline attacker working on a slow hash runs out of centuries, so 16 to 20 random characters is the honest answer for anything you care about. Longer costs you nothing here, and you are pasting it into a password manager anyway.
Do symbols matter as much as length?
Less than people expect. Turning symbols off takes the pool from 90 characters to 62, which is about half a bit per character; two extra characters buy it straight back. Use symbols where they are allowed, and where a form refuses them, add length instead of arguing with it.
Is a passphrase weaker than random characters?
Per character, much weaker. Per password, it depends only on how many words you take. Five words off this list is 64.6 bits, which is what ten characters from the full 90 character pool gives you: four times as long to type, and possible to hold in your head. Six words is 77.5 bits and past what an offline attacker on a slow hash will finish. Take words when a person has to reproduce the thing, and characters when a password manager will.
Can I use a phrase I thought of myself instead?
No, and this is the whole point of rolling for it. The strength is in the roll rather than in the words. A lyric, a quote or a sentence you composed is worth a few bits, because an attacker guesses phrases out of the same books, songs and habits you drew yours from, and cracking rigs have had wordlists built from exactly that material for twenty years. Diceware works because nobody chose the words, yourself included.
What does "bits of entropy" mean here?
It is the base two logarithm of how many different passwords these settings could have produced, and each bit doubles the work of guessing. It describes the generator, not the string. A password you invented yourself has far less entropy than its length suggests, because the count that matters is how many passwords a person might plausibly have picked, not how many arrangements of those characters exist.
Can this page produce the same password twice?
In principle yes, in practice no. The default settings have about 2¹³⁰ possible outputs, so a repeat is less likely than the machine miscalculating. The page does not keep a list to check against, because keeping a list would mean keeping your passwords.
Should I use my browser or password manager instead?
If you are filling in a signup form, yes. Safari, Chrome, Firefox and every password manager generate locally as well, and they store the result in the same step, which removes the part where a password sits on your clipboard. A page like this one is for the passwords that happen outside that flow: a database seed, a service account, a router you are setting up by hand, a value going into an environment file.

Next