[PATCH] stop using pwgen

Brian Candler b.candler at pobox.com
Sun Dec 18 17:29:38 CET 2016


On 18/12/2016 15:20, Jason A. Donenfeld wrote:
> https://git.zx2c4.com/password-store/commit/?id=f2a6078885c61040737c602a99ee75ba8009f17f
>
> Any criticism of this?
Well firstly, it doesn't even work under OSX. I tried this:

#!/bin/bash
length=25
characters='[:graph:]'
read -r -N $length pass < <(tr -dc "$characters" < /dev/urandom)
echo $pass

Result:

$ ./badpass.sh
./badpass.sh: line 4: read: -N: invalid option
read: usage: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n 
nchars] [-d delim] [name ...]

tr: Illegal byte sequence

Looking at the bash manpage:

        read  [-ers] [-u fd] [-t timeout] [-a aname] [-p prompt] [-n 
nchars] [-d delim]
        [name ...]
...
               -n nchars
                      read returns after reading nchars characters 
rather than  waiting
                      for a complete line of input.

But even changing -N to -n, OSX's tr doesn't work with binary data. The 
problem is that 'tr' is complaining about invalid unicode characters. 
You can fix it like this:

read -r -n $length pass < <(LC_ALL=C tr -dc "$characters" < /dev/urandom)

And now it works:

$ ./badpass.sh
6t-_'EOXaKZv1@#Z:yk at P\MSJ

But more seriously, there is the risk that this will consume a 
pipe-buffer (4KB? 8KB?) of entropy, only to discard most of it. That's 
extremely wasteful.

Furthermore, despite consuming so much entropy, it doesn't even 
guarantee that every password generated has at least one upper-case, 
lower-case, digit and symbol - i.e. the password may still be rejected 
by many websites!

With the default password length of 25, the probably of *not* including 
at least one digit is:

p(no digits) = ((95-10)/95)^25 = 0.062

That is, 6.2% of the time, it will generate a password with no digits. 
(Probabilities of no upper-case, no lower-case and no symbols are much 
smaller and can be ignored) (*)

I think we need a pluggable password generator, so at least we don't 
have to argue and people can use whatever generator they prefer. And as 
for a default, well pwgen is (in my opinion) better than the one in that 
patch.

Regards,

Brian.

(*) Aside: using random bytes into base64 also doesn't guarantee at 
least one symbol from each class of course.

However, if you don't care about symbols, base64 does a better job. A 
24-character base64 password, consuming 18 bytes from /dev/urandom, has 
a smaller probability of no digits:

p(no digits) = ((64-10)/64)^24 = .017

p(no upper) = p(no lower) = ((64-26)/64)^24 = .0000037

However, about half of passwords will have no symbol:

p(no symbols) = ((64-2)/64)^24 = .467

You can probably keep sites which require at least one symbol happy just 
by appending one fixed symbol to the end, like "=". This is not making 
your password any weaker, so why not?


More information about the Password-Store mailing list