Sunday, January 18, 2009

Relyiable hashes in PHP

Sometimes we need to maintain simple hashes, but at the same time we don't want to have them cracked too easily. When using a hash function on a not too complex string (like a single word), there is a risk, that the hash can be cracked using rainbow tables in few minutes.


There is a simple, but powerful solution to that problem. If we want to make sure, that the strings used for hashed generation will not be contained in any rainbow table, we need to add a custom string to the original one. That string is usually referred as salt. For higher security it's better to generate random string for each single hash. Then we need to store not only the hash, but also the salt associated to the hash. One of the options is to store them together in a way that allows to split them (which may not be a problem, since the hashing functions usually generate hashes with fixed length).

 For example:

// we have a string...
$sourceString = 'blahblah';
// generate salt through your super special salt generator
$salt = generate_salt();
// generate the hash for the combined string and add 
// the salt as a prefix to the result hash
$hashedString = $salt . md5($salt . $sourceString);
To check a target string against the hash:
// the string to be checked
$givenString = "???";
// first, extract the salt from the stored $hashedString -
// since md5 strings have length of 32, the rest is the salt:
$salt = substr($hashedString, 0, -32);
// to check the string we need to apply the same procedure
// as we did on the source string above
if ($salt . md5($salt . $givenString) == $hashedString) {
  echo "It's ok!\n";
}

Of course, you may always use more secure hashing algorithms (like sha256). On the other side, adding a salt costs almost nothing and provides additional security no matter which hashing algorithm is being used.

No comments:

Post a Comment