[wp-trac] [WordPress Trac] #21022: Use bcrypt for password hashing; updating old hashes

WordPress Trac noreply at wordpress.org
Wed Sep 18 05:59:37 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 paragoninitiativeenterprises):

 > now the prehash is down to 88 characters, respectable, but we can do
 better, was what I thought, and brought base91 to the table.

 There's a subtle reason why we recommended Base64: Migrating from base-256
 (raw bytes) to any base-N (where N is a power of 2) is easy to implement
 using constant-time arithmetic. For example:
 https://github.com/paragonie/constant_time_encoding/blob/55af0dc01992b4d0da7f6372e2eac097bbbaffdb/src/Base64.php#L213-L270

 When your new base is not an even power of 2, you have to deal with non-
 constant-time operations. This isn't straightforward: Even multiplying two
 integers can leak timing information on some processors.
 https://www.bearssl.org/ctmul.html

 RFC 4648 defines several binary-safe encodings that we can use: Base16
 (Hex), Base32, Base32Hex, Base64, and Base64Url.

 However, we don't actually need '''binary-safe''' here, what we need is
 simply "no NUL characters" (without introducing timing leaks would be
 preferred).

 If we really wanted to squeeze as much of the SHA512 hash into the 72
 character real estate as possible, we could define an alternative
 "Base128" where all of the output characters have the high bit set (i.e.
 they occupy the range `\x80 - \xFF`; the complement to ASCII) and use that
 instead of Base64. This gives us a binary blow-up of 8/7 which comes out
 to about 74 characters and is guaranteed to never have a NUL byte. (For
 the purposes of this discussion, since the high bit is set, let's call
 this hypothetical "Noble-128" so it doesn't get mistaken for an RFC 4648
 approved standard.)

 And such an algorithm would be easy to implement: Take 7 bits of input,
 prefix it with 1 bit, that's your output. (You can even use the standard
 `=` padding character for uneven inputs, since it's not a valid member of
 the `\x80-\xFF` keyspace.)

 Is this worth the extra engineering effort? Well, the keyspace of a
 base64-encoded SHA512 hash is roughly 432 bits.

 You won't ever need more than 256. https://pthree.org/2016/06/19/the-
 physics-of-brute-force

 In my opinion, bcrypt-sha512-base64 is the most elegant solution available
 to WordPress with a PHP 5.6 minimum version. Mostly because it's a one-
 liner and doesn't require a custom encoding scheme be created.

 We can bikeshed this further, but a successful argument against base64
 here means more technical debt and adding code that mere mortals do not
 understand in the WordPress codebase.

 Of course, if that's worth squeezing an extra 72 bits out of something
 that's already 174 bits in excessive of a generous security boundary, I'm
 happy to hear you out.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/21022#comment:120>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list