A password generator inspired by the Xkcd password spec
github.com
github.com
import secrets
# On standard Linux systems, use a convenient dictionary file.
# Other platforms may need to provide their own word-list.
with open('/usr/share/dict/words') as f:
words = [word.strip() for word in f]
password = ' '.join(secrets.choice(words) for i in range(4))
https://docs.python.org/3/library/secrets.html#recipes-and-b...Also EFF had prepared convenient wordlists specifically for password generation: https://www.eff.org/deeplinks/2016/07/new-wordlists-random-p...
https://raw.githubusercontent.com/agilebits/crackme/refs/hea...
which is what their own generator uses, I think.
If you're using four words, it gives you (18328⁴ / 7776⁴ ≈ 30.86) times larger space over EFF's list.
I wrote a Go package[1] that generates them (and random ones too) a while ago and also compiled a word list with about 23 thousand words[2]. I had it reviewed by a third-party, and, it seems, bias wasn’t introduced in the generation. There is a CLI app[3] using the package, if anyone is interested in something written in Go instead of Python for whatever reason.
[1]: https://git.sr.ht/~jamesponddotco/acopw-go
[2]: https://git.sr.ht/~jamesponddotco/acopw-go/blob/trunk/words/...
wriggler-airborne-genealogy-wainscotings --- awful
Now, i have had several sites that i cant accept passwords longer then 16 or 20 characters so i have to return to P@55w0rd like passwords (random, not work based).
Adding different connectors and different cases adds a lot more to remember and hardly any extra entropy
Some years ago I had a password on an account that contained a space character. One day, out of the blue, couldn’t log in. Went through the reset flow, picked another password that also happened to contain a space, still couldn’t log in.
I started poking at it and realized that I had to enter the space as `+` at the login form. It worked that way. I never quite figured out what they would’ve had to do to get the form encoding so specifically wrong.
Since then, I’ve tried to carefully consider just how “special” I want my special characters to be.
https://en.wikipedia.org/wiki/Percent-encoding#The_applicati...
It did give me inspiration for another infuriating username ^
(I should update my own similarly inspired but different generator, given it is no longer compatible with current default python: https://github.com/BenWheatley/HighEntropyPassword/blob/mast...)
Consider adding the following options:
-include-captital (default yes)
-include-lower (default yes)
-include-symbol (default yes)
-include-number (default yes)
-min-length (default 8? not sure the common limit)
How you implement these would be up to you. For my part, I generate a password and then transform it according to the options, trying to keep the spirit of diceware (as needed -- your generated pw may satisfy the options by chance, depending on the dictionary). E.g, capitalize the first letter, lower-case the last letter, (or prepend A or append z, if there aren't enough letters), put - between first and second word, transform certain vowels to numbers, that sort of thing. There are some subtleties to min-length.That is, the complexity of a password increases exponentially based on length, not so much character set. That is, the number of possibilities is squared if in your list of parameters the min-length goes from 8 to 9, changing the character set does not have as dramatic an effect.
I wouldn't know, I just assumed of the objective is to create a useful password generator.
These options aren't for increased entropy, but to satisfy restrictions real-world sites have on passwords.
(In fact, you want to be a little careful about how these are implemented to avoid/minimize the loss of entropy. It's a minor irony that these restrictions, intended to lead to stronger passwords, can result in weaker ones.)
I agree that min length is probably not relevant here though.
shuf -n 5 /usr/share/dict/wordsIt's better to use a dictionary where every word is acceptable and commit yourself to taking the first result or best of two (confining the human-selection entropy loss).
Though I don't have any suggestion for a suitable one that is just a wget away.
EFF wordlists: https://www.eff.org/deeplinks/2016/07/new-wordlists-random-p...
shuf -n 5 --random-source /dev/urandom /usr/share/dict/words | paste -sd ' ' shuf -n 5 --random-source /dev/urandom /usr/share/dict/words | tr '\n' ' '
As paste complains about working with a pipeUniquely, it uses no tracking, tries to use as few JS as possible and works completely offline. :)
https://github.com/zokier/pw/blob/master/pw.c
It's one of those things that are easier to write yourself than going through gazillion alternatives to find a good one.
You could imagine two different passwords machine generated with the same entropy under plausible selection schemes: some w$#J8fe keysplat or the selection of 5 words from a dictionary of common words. Both would be equally secure against a password guessing attacker, but the common word one would be easier for most people to remember.
If you held memorability constant, the character-splat password would be less secure.
You could imagine a hybrid, but the one you demonstrate is the kind that humans construct on their own where some characters are replaced with lookalike symbols-- these sorts of adhoc schemes are well modeled by replacement rulesets and markov-model password guessing algorithms and don't tend to add a ton of entropy. They do hurt memorability a fair bit and the better done (from a security perspective) the worse the hit on memorability.
The comic's author would probably argue just adding an extra word is better from a security and memorability perspective, or at least I argue that. :)
The whole point of xkcd/diceware style passphrases is to expand the pool. The traditional random password uses something like 96 symbol pool (printable ascii), while passphrases use a pool of thousands of symbols (length of wordlist). That is where their strength comes from.
log2(7776^5) ~= log2(96^10) ~= 64 bits
Fortunately the readme on the target page appears to show the tool defaulting to passwords of considerably higher security than demonstrated in the comic which ought to provide reasonable security under a broader set of attack models.
The big thing (in my opinion) that the comic gets wrong, and that all implementations of the password spec follow, is that if an attacker has reason to assume you might be using this style of password, then each word sort of becomes a single "character," albeit from a much larger list of possible characters. But if you introduce some random numbers or special characters into the words, it's still easy to remember and type, but becomes much more difficult to crack.
I think the "ah-ha" moment for me was realising that I needed neither to be able to remember nor to type my passwords.
Once that happens, passwords like 5Ze2vz7AdDjWbXXq start to look great rather than awful :)
Right, but the whole point is that the (hopefully) one-time pain of doing this is worth it in the long run.
If you ask users to do so themselves they tend to do so in extremely predictable ways that add l1ttle entropy!
If you do it automatically and in a way that has high entropy the result is a lot less memorable.
Probably just adding an additional word adds more entropy at less memorability cost.
I find it just as easy to remember correcthor_sebatTerystaple, and it effectively changes the attack from guessing which four words were used from a well known dictionary.
It might help to understand what people have done here: There have been absolutely gigantic plaintext password leaks. Armed with plaintext passwords and collections of very good 'dictionaries' (might not actually be dictionaries) attackers design rules to turn the dictionary into as many passwords as possible without duplication.
Why you think that is "wrong"? It's the whole idea behind passphrases to consider each word as a symbol, and it's also what the xkcd entropy calculation is based on.
> (Plausible attack on a weak remote web service. Yes, cracking a stolen hash is faster, but it's not what the average user should worry about.)
And he's right (if you don't trust the website to hash the password securely, then you should assume your password is stored in plain text anyway)
E.g. I've seen people get burned using the comics advice for "brainwallets", which is equivalent to having a published unsalted hash.
It's okay to have a confined security model, so long as you understand that's what you're doing. But users usually lack any real ability to gauge how likely password hashes are to leak just due to lack of information on how the sites operate. I think a better justification of the comic's original security level is that it's sufficient for protecting things where a compromise is only a nuisance, as is usually the case for 'random website'. But that isn't true for all password choices people make.
I think I'll be fine.
Also, I use real dice.
Let me know if I calculated that wrong. The calculation was: (6^5)^6 / 1000000 / 2 / 60 / 60 / 24 / 365
The constants:
6 - sides on a D6
5 - dice per phrase
6 - phrases
1000000 - checked passwords per second (super optimistic, unrealistic hardware, outside even government reach)
2 - half way through a hypothetical dictionary attack
60 - seconds per minute
60 - minutes per hour
24 - hours per day
365 - days per year
It only did two words and would sometimes include a number or symbol.
uvx --from git+https://github.com/beala/xkcd-password xkpa -hSince my xkcd email address has been one of my main sources of spam over the years, it's clear the site has been cracked repeatedly...