Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is password hashing, e.g. php's password_hash so slow?

I am using password_hash for password encryption. However there is a strange question, password_hash cost very long time. Here is a sample code. this code will cost more than 1 second. Is that normal?

<?php
  $startTime = microtime(TRUE);
  $password='123456';
  $cost=13;
  $hash=password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
  password_verify($password,$hash);
  $endTime = microtime(TRUE);
  $time = $endTime - $startTime;
  echo $time;
?>

the result is :1.0858609676361

like image 466
Lynn Avatar asked May 13 '15 13:05

Lynn


2 Answers

The default algorithm for password_hash, bcrypt, is designed to be slow.

http://en.wikipedia.org/wiki/Key_stretching

In cryptography, key stretching refers to techniques used to make a possibly weak key, typically a password or passphrase, more secure against a brute force attack by increasing the time it takes to test each possible key. Passwords or passphrases created by humans are often short or predictable enough to allow password cracking. Key stretching makes such attacks more difficult.

http://en.wikipedia.org/wiki/Rainbow_table#Defense_against_rainbow_tables

Another technique that helps prevent precomputation attacks is key stretching. When stretching is used, the salt, password, and a number of intermediate hash values are run through the underlying hash function multiple times to increase the computation time required to hash each password. For instance, MD5-Crypt uses a 1000 iteration loop that repeatedly feeds the salt, password, and current intermediate hash value back into the underlying MD5 hash function. The user's password hash is the concatenation of the salt value (which is not secret) and the final hash. The extra time is not noticeable to users because they have to wait only a fraction of a second each time they log in. On the other hand, stretching reduces the effectiveness of a brute-force attacks in proportion to the number of iterations because it reduces the number of computations an attacker can perform in a given time frame. This principle is applied in MD5-Crypt and in bcrypt. It also greatly increases the time needed to build a precomputed table, but in the absence of salt, this needs only be done once.

A full second is probably a little long - you could experiment with dropping $cost by one or two to bring it more to something like a tenth of a second, which will retain the effective protection while making the delay unnoticeable to your users.

like image 113
ceejayoz Avatar answered Sep 19 '22 08:09

ceejayoz


After running on 3v4l that seems perfectly normal.

Password hashing is not something you want optimize. In the words of Leigh on the hash documentation:

If you are hashing passwords etc for security, speed is not your friend. You should use the slowest method.

Slow to hash means slow to crack and will hopefully make generating things like rainbow tables more trouble than it's worth.

like image 45
thodic Avatar answered Sep 20 '22 08:09

thodic