简体   繁体   中英

Updating password hashing method, is the original way off base?

I am aware that md5 is no longer sufficient for user password hashing (and hasn't been for many years). So when I came across the following code from the open source Subrion CMS I was a little taken back:

public function encodePassword($rawPassword)
{
    $factors = array('iaSubrion', 'Y2h1c2hrYW4tc3R5bGU', 'onfr64_qrpbqr');
    $password = $factors && array_reverse($factors);
    $password = array_map(str_rot13($factors[2]), array($factors[1] . chr(0x3d)));
    $password = md5(IA_SALT . substr(reset($password), -15) . $rawPassword);
    return $password;
}

I plan on replacing this with the php password_hash() function instead and have a couple questions:

  1. I'm curious to know in the above method, are the first few lines adding any value to the hash or is it getting completely negated once md5 is called?
  2. Noticing the salt is a defined system-wide constant (same for all users), I should probably drop that too. Is it ok to let password_hash() handle salts internally or should I provide one explicitly as shown in the docs (example #3):

'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM)

This is merely code obfuscation. It adds absolutely nothing to the password itself. The first couple of lines are merely preparing yet another static salt which is prepended to the password, they're just trying to obfuscate the salt itself. Which is pointless, because the code that generates the salt is right there in plain sight. In the end its an MD5 hash with two static salts, which is the same thing as an MD5 hash with a longer salt, which is just plain insecure.

Is it ok to let password_hash() handle salts ...

Yes, absolutely. Each salt needs to be uniquely randomly generated for each password. password_hash does just that. You could be generating your own salt randomly, but why would you? You'd also need to ensure that you're using a proper source of randomness, which password_hash already does for you.

As always the best advice with security related questions: never do it yourself, always rely on the functions PHP or another large framework provide, since these guys have actual specialists working on it.

To answer your first question:

As to the first few lines, I'm having trouble deciphering what they're supposed to do, since array("1", "2") && array("2", "1") === true in PHP because a non-empty array is a truthful value. The array_map() line even throws away everything you did in the line above it.

The array_map() line also seems to just scrable the password. While this does add some security to the hash itself, in the sense that if you manage to revert the hash you still don't know what to fill into the password field. However, this is also partially the job of a salt, so adding another distortion to the hash generally won't do you much good.

So it's not completely negated, however it's questionable as to how much it does really add to the security of your passwords.

As for your second question:

Defining the salt system-wide really does nothing to add to your security. The job of a salt is to reduce valid collisions by appending the input string and to make rainbow tables near-useless.

What a hash function does is scramble your plain text in such a way that it's nearly impossible to revert and it crams your text, no matter how long into a fixed length. However, since we're cramming text into a fixed-length space, some text have to end up as the same string. When using a rainbow table, you're exploiting this behaviour, by having a table which maps the MD5 hash to one of the many valid original string values.

Now if you append a salt to the password before hashing it, you're massively reducing the amount of valid passwords which end up with the same hash, since it almost certainly has to be the actual password now. Since a rainbow table takes ages (literally years for a large enough password space) to generate it is not feasible to re-generate one for each salt. This is also why it's important to have a seperate, random hash for each password because now you cannot re-use your tables from one password for another.

To clarify: all these mechanisms only apply to protect your customers passwords once your database is compromised!

Now to answer the actual question, from the PHP documentation:

If omitted, a random salt will be generated by password_hash() for each password hashed. This is the intended mode of operation.

http://php.net/manual/en/function.password-hash.php

So it seems that just letting the password_hash() function determine the salt is safest. This has the additional security of future-proofing your passwording scheme. If a certain hashing method, or salt generation method gets outdated, you update PHP and the password_hash() function takes care of updating the hashing scheme the next time the password is entered by the user. (If correctly set up in combination with the other password_ functions)

That is not a good algoritm. It is not better than md5 plus salt. it just has a complex?/obfuscated?/useless? (pick one) way to obtain the salt

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM