PHP password vault with HMAC + nonce - is random randomness important?

For several years, I asked here about stackoverflow on 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); } 

In response, it is suggested to use random nonce. Is there any advantage in that you have a random exception compared to simple unique ones?

For example, each user can have his own identifier, which does not change. However, let them assume that the user IDs are sequential (built with MySQL auto-growth function) and therefore are not random. Would a user id be good or nonrandom?

Now each user can choose a username. Each user has a username that does not change, and two different users cannot have the same username. Usernames are still not random, but they are also not sequential. Will usernames be good enough like nonce? Would it be better than using a user id?

+6
security php password-storage hash hmac
source share
3 answers

THIS IS ALL ON THE PROVISION THAT DOES NOT BE SUBJECT TO SALT ...

If by nonce you mean salt, then yes, which requires more rainbow tables. Usually once a salt of 20 characters is enough, but for extreme security conditions you will need a new random salt for each password.

Also a good choice in the slow hash is http://www.php.net/manual/en/function.hash.php#89574 , without sarcasm. But I like ripemd.

I do not see the bottom half of your answer. To develop: Nonces are used to prevent the use of rainbow tables. Whether the identifier works depends only on the length of the identifiers. Randomness is not technically important, but simply makes more rainbow tables. For example, suppose you used the character "a" as nonce, and the password was 2 characters long, you need to create a rainbow table a-aa, a-ab a-ac, etc. If you use a random case, every time, perhaps all permutations of β€œa” should be performed + all permutations of other random characters.

But in general, creating rainbow tables takes a lot of time. So if you come up with a salt that has long remained its rainbow table, it does not exist.

+2
source share

I found that there was a pretty good tutorial written online on this topic. I don’t quite remember where on google I found it, but let me see if I can break the function well enough, since it is right in front of me ...

First, a function can create a key length of any size. I took the liberty of commenting on this quite seriously ...

 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); } 
  • The first thing he does is figure out the length of the hash.
  • Next, it is determined how many blocks are required for the specified key length
  • Then it initializes the hash (key) to return
  • sets a for loop that each block will create
  • accepts an initial block hash with a block counter in binary format added to the salt
  • starts a loop to iterate the block $ iter_count times (create the hash itself)
  • XOR each repeats and adds it to $ iterated_block (xor previous hash to current)
  • XOR cycle ends
  • add $ iterated_block to $ key for each block
  • completes the loop cycle
  • return key

I believe this is probably the best way to do this. Maybe I'm too paranoid?

+2
source share

To store a password, just use:

 sha512(salt + password) 

salt must be random and unique for each user. Random salt will make unpredictable attacks on hash tables impossible: each user will need their own calculated hash tables. If you use non-random salt, then the likelihood that a table with a pre-calculated table will be higher will be higher.

Putting salt before the password will help to hide hash patterns in case some users have the same password.

Nonce is not required because it is designed to prevent a response attack. This protection is not possible in your architecture.

Using HMAC to prevent collisions is useless because: a) we do not use the hash for the MAC, b) so that you need to calculate about 2 ^ 256 values ​​for a 50% chance of collision for SHA-512. And 2 ^ 256 is really an astronomical number.

0
source share

All Articles