A few years I asked here on stackoverflow about how to make PHP password storage safe. The main answer suggests using the following hashing algorithm:
function hash_password($password, $nonce) {
global $site_key;
return hash_hmac('sha512', $password . $nonce, $site_key);
}
The answer suggests using a random nonce. Is there any advantage in having a random nonce over simple unique nonces?
For instance, each user can have its own ID which does not change. However, let's assume user IDs are sequential(built with MySQL's auto increment feature) and therefore not random. Would the user ID be a good nonce or is randomness important?
Now, each user can pick an username. Each user has its own username which does not change, and two different users can't have the same username. Usernames are still not random, but they aren't sequential either. Would usernames be good enough as a nonce? Would it be better than using the user ID?
Create $hash = SHA256 ($nonce$password) and store $nonce together with $hash in the database. Why isn't the following substantially better than the above? Create $long_string once and only once. Store this as a constant in the application code. $long_string could f.x. be 2 kilobyte of random characters. Obtain $password from the end user.
A Nonce is a number or a token used only once. You can use Nonce in your pages or forms to add an extra layer of security to your App and one of its features is to differentiate humans from bots. Today, I will show you how to create a simple Nonce in PHP, and how you can validate it.
When hashing passwords, the two most important considerations are the computational expense, and the salt. The more computationally expensive the hashing algorithm, the longer it will take to brute force its output. PHP 5.5 provides a native password hashing API that safely handles both hashing and verifying passwords in a secure manner.
HMAC may be used instead of a raw hash function to strengthen a password-verification system, but in a different setup. Given a system which checks passwords with salts and iterated hash functions, you can replace the hash function with HMAC, using a secret key K.
THIS IS ALL ON THE ASSUMPTION THAT A NONCE IS A SALT...
If by nonce you mean a salt then yes that requires more rainbow tables to be made. Usually once salt over 20 characters suffices, but for extreme security conditions you would want a new random salt for each password.
Also good choice in a slow hash http://www.php.net/manual/en/function.hash.php#89574, no sarcasm. But I like ripemd.
Didnt see the bottom half of your response. To elaborate: Nonces are used to prevent the use of rainbow tables. Whether the ID's would work depends merely on the length of the IDs. Randomness is not technically important, but just makes more rainbow tables required. An example would be, lets say you used a character "a" as a nonce and the password were 2 characters long, a rainbow table of a-aa, a-ab a-ac and so on would have to be created. If you use a random one each time maybe all the permutations of 'a' would have to be done + all the permuatations of the other random characters.
But in general making rainbow tables take quite a long time. So if you come up with a salt thats long its likely the rainbow table for it doesnt exists.
I found that there was a fairly nice tutorial written online about this topic. I don't quite remember where on google I found it but let me see if I can break the function down well enough myself as it is right in front of me...
First the function, it can create a key length of any size. I took the liberty of commenting it fairly heavily...
function pbkdf2($password,$salt,$iter_count = 1500,$key_length = 32,$algorithm = 'sha512')
{
/*
@param string password -- password to be encrypted
@param string salt -- salt to encrypt with
@param int iter_count -- number of times to iterate blocks
@param key_length -- length of key to return
@param $algorithm -- algorithm to use in hashing
@return string key
*/
//determine the length of the hahs
$hash_length = strlen(hash($algorithm,NULL,TRUE));
//determine the number of key blocks to compute
$key_blocks = ceil($key_length/$hash_length);
//initialize key
$key = '';
//create the key itself
//create blocks
for($block_count = 1;$block_count <= $key_blocks;$block_count++)
{
//initalize hash for this block
$iterated_block = $block = hash_hmac($algorithm,$salt.pack('N',$block_count),$password,TRUE);
//iterate blocks
for($iterate = 1;$iterate <= $iter_count;$iterate++)
{
//xor each iterate
$iterated_block ^= ($block = hash_hmac($algorithm,$block,$password,TRUE));
}
//append iterated block
$key .= $iterated_block;
}
//return the key
return substr($key,0,$key_length);
}
I feel this is probably the best way to do this. Maybe I am too paranoid?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With