I have been presented with some custom PHP code for salting passwords and applying multiple rounds of hashing.

It looks reasonable, but I fear home-grown crypto.

Is there an existing password salting and multiple hashing algorithm which I could use instead of code from a non-cryptographer.

The algorithm needs to accept a password, a salt and the number of rounds.

I've found bcrypt, which looks appropriate, but I'm concerned that it's old.

  • $\begingroup$ My go-to is a modified PBKDF2-SHA512 with a 48 byte output, stored in PHC format with the round count and output size, and modified to perform a single initial hash on the password before sending it to PBKDF2. I just wrote a PHP version of this earlier in the week $\endgroup$ – Richie Frame Nov 17 '17 at 9:47
  • $\begingroup$ @RichieFrame I've just come across wiki.php.net/rfc/argon2_password_hash - are there issues with this? $\endgroup$ – fadedbee Nov 17 '17 at 10:13
  • $\begingroup$ that does not exist yet, it is a proposal for the new PHP 7.2, and only if the Argon2 library is enabled, which is not a requirement (yet) $\endgroup$ – Richie Frame Nov 17 '17 at 10:22
  • $\begingroup$ there are a few blogs discussing this topic, you may be interested - including references to some frameworks for php crackstation.net/hashing-security.htm $\endgroup$ – gusto2 Nov 17 '17 at 10:36

Current best practice does include bcrypt, which is the same as PHP's built in password_hash() function. Future best practice will probably be Argon2.

Other widely used secure KDF options include PBKDF2 with SHA512 or SHA256 as the hash function, and scrypt. scrypt and bcrypt differ from PBKDF2 in that they can use large amounts of memory, and thus resist cracking on commodity hardware better, which has more processing power than memory in the context of hash brute forcing.

bcrypt and PBKDF2 do have a specific issue, which is that a large password can cause the algorithm do behave in a way one would not expect. In bcrypt, there is a hard limit on input text, and a long password is simply truncated. In PBKDF2, the password is used as a direct input to HMAC, and if it is too large, the hash function must process the data more than once. My fix is to simply hash the password once with SHA512 before sending it to the KDF, as that makes the password input 64 bytes, which is within the bcrypt limit, and needs only a single hash with PBKDF2-SHA512.

Storage in the database is also an issue. Best practice is to use either the Modular Crypt Format or the PHC String Format. The trend is to use the PHC format over MCF as it is still based on MCF, but more flexible, and with more specific rules. PHC format with parameters allows forwards/cross compatibility and easy migration.

An example PHC format string:


Where : algorithm = bpmhash_sha512 (pbkdf2 with 1 round prehash) i = the round count as 5 l = the output in bytes as 48 salt = caaaaaaaaaaaaaaaaaaaaaaaaaaaaaab hash = HvrCpcKm209ikRst7gpsWbh1p5QyiA33R6iovxo0da6CX+lU1wKw0SserPtb6U3O


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.