[wp-trac] [WordPress Trac] #21022: Use bcrypt for password hashing; updating old hashes
WordPress Trac
noreply at wordpress.org
Wed Sep 18 00:31:11 UTC 2019
#21022: Use bcrypt for password hashing; updating old hashes
-------------------------------------------------+-------------------------
Reporter: th23 | Owner: (none)
Type: enhancement | Status: new
Priority: normal | Milestone: Future
| Release
Component: Security | Version: 3.4
Severity: major | Resolution:
Keywords: 2nd-opinion has-patch needs-testing | Focuses:
dev-feedback |
-------------------------------------------------+-------------------------
Comment (by my1xt):
@mbijon
you kinda overlooked something, so let me summarize (still very long so
take your time, there are both code examples and math ahead).
Bcrypt has a 72 length password limit
how to deal with longer Passwords, just truncating kinda sux, especially
when we are playing with wordlist passwords?
You said yourself that passphrases are a strong recommendation, the big
problem is the bcrypt password length limit though, the idea of wordlist
passwords us completely right but the entropy per byte of the phrase is
very low. if we knew the list, we could obciously convert this into a byte
sequence and be done with it, but we don't.
The idea of @mobby2561 was to SHA-512 the password and throw THAT into
bcrypt, basically
{{{#!php
<?php
$prehash=hash("sha512",$password);
$final_hash=password_hash($prehash,PASSWORD_BCRYPT);
}}}
Paragon later meant that the hex output is kinda large with 128 chars and
suggested to use a base64 hash instead of a hex one, like this:
{{{#!php
<?php
$prehash_bin=hash("sha512",$password,true);
$prehash_enc=base64_encode($prehash_bin);
$final_hash=password_hash(%prehash_enc,PASSWORD_BCRYPT);
}}}
now the prehash is down to 88 characters, respectable, but we can do
better, was what I thought, and brought base91 to the table.
using a little character counting website SHA512 went for 79 characters,
so basically just 7 characters get thrown out.
{{{#!php
<?php
include("base91.php");
$prehash_bin=hash("sha512",$password,true);
$prehash_enc=base91_encode($prehash_bin);
$final_hash=password_hash(%prehash_enc,PASSWORD_BCRYPT);
}}}
so the idea is basically to press as much of a password into the bcrypt as
we can. obviously a password with more than 512 bits of entropy won't fit
into SHA-512 without losing some entropy this way but it would fall out
anyway with normal bcrypt.
----
Time for some Math:
the idea is that if we say go for a more optimal case and assume we have a
really big wordlist (the one I extract from 1password usually has around
18k words, the one I got a few weeks ago is 18 319, it is 131 879 bytes
long, subtracting 18318 (newlines) from it we get 113 561. dividing that
by 18 319 gives us an average of 6,2 characters per word.
I think I am pretty generous here, diceware only comes along with 7776
words, so yeah you will probably need a LOT more characters to get the
same amount of entropy.
so now we need some harder math so take a breath, look at this and let me
explain every step.
https://www.wolframalpha.com/input/?i=log18319(2^512)*6.2
from the inside to outside I do the following.
first I let it calculate the possibilites for a 512-bit secure password,
aka before we break off the entropy from SHA512.
second I use the log with a base of 18319 to calculate how many words are
needed for that
(to clarify a log with base (say 2) of a number (say 8) = x solves the
question
2^x^ = 8 with x being obviously 3)
that is about 36 words, quite a lot and most people wont use that sure.
finally we multiply by 6,2 (the average word length and get (not including
any spaces) 224 characters before we reach an entropy of 512 bits. no way
that's gonna fit into bcrypt.
on the other hand This equation:
[https://www.wolframalpha.com/input/?i=log2(18319^(72%2F6.2))]
tells us how much we CAN fit into an average 72 character wordlist
password based on the assumptions. around 164 bit, which is definitely
VERY good for a password, but reminder that WP currently has had a 4096
character limit for passwords. a straight cut to 72 would be a but
dramatic
so after the main math is out let's talk a bit more about the cutting.
the hex sha512 cut 128 to 72, we are down to 288 bit, base64 went down
from 88 characters, 418,9 bit, I think we can see where this is going, and
finally base91 with 79 chars has 466,6 bit after the 72 character
truncation
--
Ticket URL: <https://core.trac.wordpress.org/ticket/21022#comment:116>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list