[wp-trac] [WordPress Trac] #39499: Migrate Password Hashing from 8192 rounds of salted MD5 to Argon2i v1.3

WordPress Trac noreply at wordpress.org
Fri Jan 6 08:28:34 UTC 2017

#39499: Migrate Password Hashing from 8192 rounds of salted MD5 to Argon2i v1.3
 Reporter:  paragoninitiativeenterprises  |      Owner:
     Type:  enhancement                   |     Status:  new
 Priority:  normal                        |  Milestone:  Awaiting Review
Component:  Security                      |    Version:  trunk
 Severity:  normal                        |   Keywords:
  Focuses:                                |
 This is a sibling ticket to #39309 to greatly enhance the security of
 WordPress blogs the whole world over. It is not a duplicate of #21022 as
 that pertains to bcrypt.

 Currently, WordPress uses 8192 rounds of Salted MD5 for password hashing:

 Salted MD5 is a weaker version of PBKDF2-MD5 with a low number of
 iterations and no GPU resistance. Migrating to bcrypt has been proposed
 (see #21022 for details), but bcrypt support in PHP < 5.3.7 isn't
 consistent; nor is it secure.

 = Proposal: Switch to Argon2i for Password Hashing =

 Argon2i is available in libsodium, accessible via the `crypto_pwhash` API.

 Paragon Initiative Enterprises is currently developing a pure-PHP polyfill
 for the libsodium extension (currently available in PECL) compatible with
 PHP 5.2.4+. Once it's complete, stable, and independently audited by third
 party security experts, WordPress should consider adopting this library to
 facilitate a long-overdue security enhancement.

 Our library is available on Github:

 == Migrating Legacy Hashes ==

 We recommend the process outlined here: https://paragonie.com/blog/2016/02

 In more WP-specific terms: On the next automatic update, immediately re-
 hash all users' password hashes with Argon2i. Store the old **salt** (not
 the full hash) alongside the Argon2i hash, and provide some way of
 identifying legacy hashes.

 When a user authenticates:

 * Is this a legacy hash?
   * Pre-hash with Phpass (in portable mode, as per WordPress today)
   * Use the $P$ hash as the password for `crypto_pwhash_str_verify()`
   * If the password validates, calculate a new `crypto_pwhash_str()` of
 the user's given password and store that in the database. Clear the old
 salt and any legacy password indicators.
 * Otherwise, just use `crypto_pwhash_str_verify()`

 WordPress should absolutely NOT consider an "opportunistic upgrade"
 strategy. Otherwise, you're no better than Yahoo:

Ticket URL: <https://core.trac.wordpress.org/ticket/39499>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform

More information about the wp-trac mailing list