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.