After reading about salts password hashing Id like to implement a simple version for an admin area to a site Im building.
If you have any good links with code that have
Well, here's what I would do:
function makeToken($length = 16) {
if ($length > 16) {
$ret = '';
while ($length > 0) {
$ret .= makeToken(16);
$length -= 16;
}
if ($length < 0) {
$ret = substr($ret, 0, $length);
}
return $ret;
}
$stub = '';
for ($i = 0; $i < 100; $i++) {
$stub .= chr(mt_rand(1, 254));
}
$hash = sha1($stub);
$hashLen = strlen($hash);
$ret = '';
for ($i = 0; $i < $length; $i++) {
$ret .= $hash[mt_rand(0, $hashLen - 1)];
}
return $ret;
}
function makeSaltedHash($string, $salt = '') {
if (empty($salt)) {
$salt = makeToken();
}
$hash = '';
for ($i = 0; $i < 200; $i++) {
$hash = sha1($hash . $salt . $string);
}
return $hash . ':' . $salt;
}
function verifySaltedHash($string, $hash) {
if (strpos($string, ':') === false) return false;
list ($base, $salt) = explode(':', $hash);
$test = makeSaltedHash($string, $salt);
return $test === $hash;
}
The rational is this:
First, generate a random salt (this will always return a hex string, so it can be used for tokens etc). Then loop over a hashing function (sha1 in this case) more than 1 time. This is so that it becomes more expensive to generate a rainbow table (200x as expensive in this case) while adding relatively little expense to generation.
Usage:
To generate a hash:
$hash = makeSaltedHash($password);
To verify the hash:
$bool = verifySaltedHash($password, $savedHash);
To generate a token (CSRF protection, session_id, etc), you can do it a few ways:
Fixed Length:
$token = makeToken(32);
Random Length:
$token = makeToken(mt_rand(64,128));
Edit: Increased the repetitions on sha1 in the hashing function.
If you need really secure hashes, please use the Portable PHP hashing framework.
I'd also recommend this Month of PHP security article that deals extensively with password hashing and the security of hashes.