[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