7 ms·
Show HN: WordPass – password generator giving over 90 bits of entropy
- dasil003 12y agoI don't understand how 4 random words from a 50k dictionary gives 90 bits of entropy. 50k ^ 4 => 6.25e+18 2 ^ 90 => 1.24e+27 Am I missing something?
- saurik 12y agoThe words are separated (and I guess terminated) by a random symbol (of which there are apparently 32 possibilities) or (randomly) a random two-digit number. log(50000^4*(100+32)^4)/log(2) = 90.6
- ghshephard 12y agoDoesn't that defeat the "Trivial to remember" part of the xkcd concept of "Trivial to remember, hard to guess?"
- mtct 12y agohttps://www.schneier.com/blog/archives/2014/03/choosing_secure_1.html https://www.schneier.com/blog/archives/2014/03/choosing_secu...
- stcredzero 12y agoThat means you only have 7 entities to remember, which is supposed to be what humans can handle easily. (Though I understand now that this is stale knowledge.)
- aggie 12y agoThe number refers to the capacity of working memory and has indeed been revised over time. It's a complicated issue, but 4 units of information is now considered a more accurate approximation. But if you're remembering a password, you're dealing with long-term memory, which doesn't have this limitation. http://en.wikipedia.org/wiki/Working_memory#Capacity http://en.wikipedia.org/wiki/Working_memory#Capacity
- miga 12y agoLong-term memory usually accepts most information from short-term memory not direct sensory input, so it is easier to memorize when you break down things in chunks first.
- atmosx 12y agoCan you offer a link on how do you do these measurements and what exactly do they mean? Reading the wikipedia article about entropy in (computing) I stumbled across this[1]: " Around 2011, two of the random devices were dropped and linked into a single source as it could produce hundreds of megabytes per second of high quality random data on an average system. " What does it mean high quality random data in this context?. I mean 'random' is a precise definition, something 'is random' (e.g. distance of next prime :-P, kill Riemann) or 'not random' (distance of next prime if Riemann's ζ(s) is solved). [1] https://news.ycombinator.com/user?id=dasil003 https://news.ycombinator.com/user?id=dasil003
- tinco 12y agoThat's random in maths, we're not talking maths here. In the real world, random is a value that's hard to predict. For example a dice throw has a high quality of random in normal circumstances. A low quality random source would depend on some variables that make it easier to predict the next random number (perhaps just statistically). The worst quality random source would be pseudo-random numbers, where the value of each next random number directly follows from the previous value and perhaps some secret second value. It might be distributed like a true random number, but eventually the secret could be guessed and the numbers would become predictable.
- darkmighty 12y agoA simple explanation is that "randomness" here is related to (logarithm of) the minimum average time [1] you would take to guess the password correctly (H=sum(pi * log(1/pi)). Since the random number generator supposedly gives an uniform distribution over a set of words, this simplifies to H=n(1/n log(n))=log(n). [1] Your average time is at least t* =1/2 * 2^H, so log( t* )>H-1.
- ef4 12y ago"Distance of next prime" is not random, it's entirely deterministic. It's a well-defined function. Just because we don't have an analytical solution for it doesn't make it random. As for "high quality", some random variables are less predictable than others. A weighted coin that comes up heads 51% of the time is still random (not deterministic), but more predictable than a fair coin.
- deleted 12y ago[deleted]
- Ruud-v-A 12y agoI wrote a post about this some time ago: http://ruudvanasseldonk.com/2012/07/07/passphrase-entropy http://ruudvanasseldonk.com/2012/07/07/passphrase-entropy
- ghshephard 12y agoimport random, re lines=[re.sub('[-!.,;:]',' ',x).split() for x in open('in').readlines()] w=set() for l in lines: w=w | set(l) random.sample(w,4) Hrm, for romeo and juliet I get some interesting combinations... ['unseen', 'iron', 'Catling', 'baked'] ['grove', 'press', 'Aurora', 'garish'] ['agate', 'She', 'drybeat', 'rather'] ['flowed', 'sails', 'wed', 'masks'] ['spilt', 'cage', 'Remembering', 'stiff'] ['heartsick', 'shame', 'enjoin', 'weeping']
- wyager 12y ago> import random, re You'll want to replace random with a cryptographically secure RNG.
- peteretep 12y agoCould you describe a practical attack against this password generator based on how it actually works? Specifically what information you would need to be in possession of in order to exploit it, and then a description of how you would - again, in practice - exploit that, inside a practical timeframe. Thanks.
- wyager 12y agoI'm not familiar with python's non-secure PRNG implementation. Usually it involves the fact that A)these PRNGs have small entropy pools, so you can check the entire state space quickly and B)they have non-uniform outputs, so you can do probabilistic attacks.
- leo_santagada 12y agopython and ruby use a mersene twister prng: http://en.wikipedia.org/wiki/Mersenne_twister http://en.wikipedia.org/wiki/Mersenne_twister it is a good prng... but it is not crypto secure. as an easy patch just use urandom: http://cryptography.readthedocs.org/en/latest/random-numbers/ http://cryptography.readthedocs.org/en/latest/random-numbers...
- 12y ago
- tinco 12y agoI made one in Ruby a few weeks ago. Please don't do what ghshephard does below and blindly import random. It's actually quite important that you use a secure random generator, or your entropy will be drastically reduced. My solution is here, don't use it unless smart people have confirmed that it works: https://github.com/d-snp/wachtwoord/blob/master/wachtwoord.rb https://github.com/d-snp/wachtwoord/blob/master/wachtwoord.r... Also smart people: please let me know if I've done anything stupid here, I actually use passwords generated by this tool. For people who don't enjoy reading Ruby: My tool reads in a dictionary file, drops any too small words because they don't have enough absolute entropy and too long words because they're harder to remember (for Dutch anyway, your mileage might vary in your own language). You can vary the amount of words you want to have in your passphrase, and the tool will print how much entropy the password has if the attacker is aware that you're using this scheme and this dictionary file, but not aware of the random values spitted out by the random generator to pick the words. It will also spit out a cheesy ballpark estimate as to how long it might take an attacker to crack this password with reasonable effort, you can tweak what reasonable effort means for your context. What currently is a reasonable attack depends heavily on the hashing scheme you employ.
- jkolash 12y agoHere is my version sort -R --random-source=/dev/urandom /usr/share/dict/words |tail -n5| tr '\n' '#' Sample Output: pyodermia#personable#sunburnproof#disarray#lawyery#
- keithpeter 12y agohttps://www.schneier.com/essay-246.html https://www.schneier.com/essay-246.html Oulipo rules. Latin squares. Nursery texts. Maps. Anyone working on a generator based on this kind of approach?
- miga 12y agoCould you elaborate and give pointers to what "Oulipo rules" and others are?
- keithpeter 12y agoOulipo was a silly 'organisation' invented by some writers in Paris after the second world war. The members included mathematics lecturers and writers interested in producing texts according to routines or with constraints. George Perec walked the streets of Paris systematically for some months according to a routine derived from a double latin square, and then wrote about what was happening at each location at a specified time. I was alluding to the idea easily remembered rules for selecting characters from a text known to the person.
- arh68 12y agoThis inspired me to write a rudimentary version in bash/C: ----pwgen.sh #!/usr/bin/env bash DICT=/usr/share/dict/words NL=$(wc -l $DICT | sed 's_[ \t]*\([0-9]*\).*_\1_') PW="" for i in {1..4}; do RAND=$(./arc4random) LINE=$[$RAND % $NL] WORD=$(sed -n $LINE"p" < $DICT) PW=$WORD" "$PW done echo $PW ----arc4random.c #include <stdio.h> #include <stdlib.h> int main() { printf("%u\n", arc4random()); return 0; } They're not always easy to remember, though, at least for me: > ./pwgen.sh interdepartmental anesthyl intrabranchial physiolatrous
- cynwoody 12y agoYour little script performs amazingly well on my Mac, coming in at about 165 ms, quite a bit faster than I expected. If your script is too fast for you, you could consider reading the dictionary into a bash array instead of using sed. My /usr/share/dict/words contains 234,936 words. As a point of comparison, here is a Python version that clocks in around 107 ms: #!/usr/bin/env python from random import SystemRandom as r with open('/usr/share/dict/words', 'rb') as f: lines = f.readlines() print ' '.join(r().choice(lines).rstrip() for x in xrange(4)) However, I don't know how well SystemRandom compares to arc4random in terms of crypto.
- jzwinck 12y agoIf you're set on using arc4random it's no big deal to use ctypes to invoke it from Python. Bash is quick to bang out but it's funny how your parent needs to compile a C program then invoke it N times per bash script run. Using Python for this is an obvious choice.
- arh68 12y agoYes thanks for pointing that out, I wrote a slightly faster version below. I took your advice and wanted just a single invoke on the C program, so I modified it to take an argument. I'm satisfied! > cat arc4random-v2.c #include <stdio.h> #include <stdlib.h> int main(int argc, char** argv) { if ( ! (argc == 1 || argc == 2) ) { printf("usage: %s [n_output]\n", argv[0]); } else { int n_iter = (argc == 2) ? atoi(argv[1]) : 1; for (int i = 0; i < n_iter; i++) { printf("%u\n", arc4random()); } } return 0; } > ./arc4random 3 4282823399 333796506 762478899 > cat pwgen-v2.sh #!/usr/bin/env bash dict=/usr/share/dict/words n=4 # of words to include in passphrase nl=$(wc -l $dict | sed 's_[ \t]*\([0-9]*\).*_\1_') fmt_flag() { echo $[$1 % $nl] | sed -n -e 's_^_-e _' -e 's_$_p_p' ; } flags=$(./arc4random $n | while read -r i; do fmt_flag "$i"; done) words=$(sed -n $flags < $dict) echo $words > time ./pwgen.sh liparite evade retiringly spacious real 0m0.268s user 0m0.251s sys 0m0.015s > time ./pwgen-v2.sh latherin prideling thumbscrew unraveled real 0m0.082s user 0m0.072s sys 0m0.013s EDIT: note that the single call to sed results in alphabetical/dictionary-dependent results... (!) oops
- euank 12y agoWe need to just get away from remembering passwords. Something like Mozilla Persona would have been great, but since it didn't catch on we already have KeePass (and for mac/linux, keepassx2 alpha works quite well). These cutesy little passwords might be fairly strong and easy to remember, but it hardly matters because having to remember them results in reuse and an upper bound on the possible entropy. The human mind has more important things to do than remembering thousands of bits of entropy (spread among all your passwords, you should have at least that much)... we made computers to remember this sort of stuff for us. If these passwords aren't meant to be remembered, but put in keepass, then there's no point in not just upping the entropy by randomizing at the character granularity. KeePass makes it much easier; you have it generate you 300 bits of entropy passwords (or whatever you feel is enough), and then you can focus all your security efforts on that one database file. Having a "single point of failure/password" doesn't have to be bad because it lets you guard more closely against that single point.
- tomberek 12y agoA similar scheme used to save, retrieve, and publish elm code: http://tomberek.insomnia247.nl:5055/xkcd/flowerbed/too/sociologically/defiantly http://tomberek.insomnia247.nl:5055/xkcd/flowerbed/too/socio... Using 'Publish' will produce http://tomberek.insomnia247.nl:5055/xkcd/2797191408452820889 http://tomberek.insomnia247.nl:5055/xkcd/2797191408452820889 which is just the output page without access to an editor. Edit: go to http://tomberek.insomnia247.nl:5055/try http://tomberek.insomnia247.nl:5055/try to make your own
- kolev 12y agoHow do you install stuff like this? I've never touched Haskell, I tried "cabal install wordpass", but it seems it doesn't exist.
- samstokes 12y agoAssuming you mean wordpass doesn't exist: try "cabal update" first. If you mean cabal doesn't exist, you'll need to install the Haskell Platform first. There may be a package for your distro (or Homebrew).
- kolev 12y agoThanks, "cabal update" did it for me. I guess I have no more excuses to dive into Haskell!
- pjaspers 12y agoI made something similar [0] but based on Diceware [1] and a book you pass on to the app. It generates passphrases by using words from the book. [0] https://github.com/pjaspers/frasier https://github.com/pjaspers/frasier [1] http://world.std.com/~reinhold/diceware.html http://world.std.com/~reinhold/diceware.html
- robgering 12y agoQuick and dirty Bash one-liner: shuf -n4 /usr/share/dict/words | sed "s/'s//g" | tr -d "\\n"; echo;
- csirac2 12y agoMy favourite tool is simply gpw(1). It tries to generate semi-pronounceable words that aren't necessarily dictionary words: $ gpw rpreence rethersi atencend rostrass rtschers pocrevoy umblowfl disalsit rmsturnu tinfethe I then have a perl script which can give me slightly more interesting capitalizations and numbers: nessinea 258 rusness redoodr rInGLe 893 orinGsT 87 iNdaPeRv 3423 RisEv screar bullys I've become quite good at remembering these. I can usually remember them even if I go a month or two between usages. It's hard to explain, but it seems to require a different memorization effort that somehow sticks better into my long-term memory than with random dictionary words. (1) http://manpages.ubuntu.com/manpages/hardy/man1/gpw.1.html http://manpages.ubuntu.com/manpages/hardy/man1/gpw.1.html
- miga 12y agoYes, it is critical constraint - if you find it easy to remember. What's the size of random password space there?
- csirac2 12y agoYou just prompted me to read the source code :-) gpw.c has this comment at the top: /* GPW - Generate pronounceable passwords This program uses statistics on the frequency of three-letter sequences in your dictionary to generate passwords. The statistics are in trigram.h, generated there by the program loadtris. Use different dictionaries and you'll get different statistics. This program can generate every word in the dictionary, and a lot of non-words. It won't generate a bunch of other non-words, call them the unpronounceable ones, containing letter combinations found nowhere in the dictionary. My rough estimate is that if there are 10^6 words, then there are about 10^9 pronounceables, out of a total population of 10^11 8-character strings. I base this on running the program a lot and looking for real words in its output.. they are very rare, on the order of one in a thousand. ... I'm not really in a position to properly figure this out... for a start, it's commonly claimed that there are 1M words used in English however my local /usr/share/dict/words has only 100K entries (and a even lot of those seem redundant). Assuming my gpw binary was "trained" on a 1M wordlist, and that my algorithm averages three 8-char strings per passphrase... and we take the comments at face-value, i.e. 10^9 possibilities per 8-char string generated. I'm going to pretend I can competently use Mlog2(N) to estimate that three such strings might make up 3log2(10^9)=89 bits of entropy. Throw in a 0-9999 number, let's pretend that's worth 13-ish bits, let's call it 100 bits? I haven't factored in the capitalizations yet, and I'm not sure how much the random placement of the numbers and the random lengths of each "word" are worth. IANACG (I am not a crypto guy) but that seems like a huge number of bits and so this is likely completely wrong (I'd start with going back to trying to properly analyze how many combinations my gpw binary can actually produces in an n-char string - that 10^9 combinations from a 10^6 wordlist needs testing).