2

I was going through this article and found the following format of the hash that is returned while we use bcrypt. I found that this hash is supposed to be stored in the database (in a varchar(60) format or so) and used when any user authentication is required.

format of a return value from password_hash()

My doubt is that if my database gets compromised the attacker will already be knowing the algorithm, the cost and the salt I am using which will make his job very easy. I think so because now he doesn't even need to guess the algorithm (bcrypt,SHA,MD5,etc.) he has to use to get the user's password by brute force.

Instead I feel I should be using only the last part (the part after the last $) and add the other part in my script before the matching like this

<?php

$options = array('cost' => 11);
echo password_hash("akki", PASSWORD_BCRYPT, $options)."\n";
// $2y$11$mrblnrK01GWt4g55.Z8Zs.1RslouNzBqCVW826QfBEuaRaVyq96c2

?>

I can store the mrblnrK01GWt4g55.Z8Zs.1RslouNzBqCVW826QfBEuaRaVyq96c2 part in the database

To verify a user provided password against an existing hash, I can use the following function:

<?php
// Query the db to get $hash.
$hash = 'mrblnrK01GWt4g55.Z8Zs.1RslouNzBqCVW826QfBEuaRaVyq96c2';
$hash = '$2y$11$'.$hash;

if (password_verify('akki', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>

I found a similar question here but it doesn't tell why showing the algorithm (and cost) is not a risk although I understand why revealing the salt is not an issue. Also the reason that this might help when I try to change my algorithm or cost doesn't seem worth the risk.

Community
  • 1
  • 1
akki
  • 2,021
  • 1
  • 24
  • 35
  • 1
    The whole thing should go in the database. It doesn't matter if the attacker gets the salt and the algorithm. These are not supposed to be secret. Additionally, if you're not storing the salt in the database, your probably using the same salt for every password, which you shouldn't be doing. Salts should be randomly generated for each record and used once. – user229044 Dec 22 '14 at 06:32
  • 1
    As a general rule, leave the security up to the mathematicians designing the hash functions. It is infinitely better than us mortals [trying to obscure our protocols](http://en.wikipedia.org/wiki/Kerckhoffs%27s_principle). – Joel Dec 22 '14 at 06:53
  • @Joel I am sure leaving the security upto them is the best thing I can do..just wanted to know how its working :-) – akki Dec 22 '14 at 08:30
  • @meagar I agree with you and that is exactly what I read everywhere.My question is "why" ? – akki Dec 22 '14 at 11:49

1 Answers1

3

why showing the algorithm (and cost) is not a risk

Because brute forcing it will still be virtually impossible. There is no meaningful increase in risk. Even knowing the algorithm and cost used it will take many many years per password.

The only thing you're doing by not storing that information is making it more difficult to upgrade the algorithm and/or increase the cost at a later date. These things need to be upgraded as things like more powerful hardware, new methods of attack, and stronger algorithms come into play.

Practical for most purposes is to keep the time it takes to compute a single hash up around 0.3-0.5 seconds.

Anything you do to make upgrading and rehashing more difficult decreases the likelihood that it will happen. This is what introduces risk.


What do you do when an effective avenue of attack surfaces against the hash function you're using?

This isn't theoretical. A lot of people were plenty happy with SHA1 until GPU-accelerated attacks showed up.

If you're storing the entire string it's trivial to run it through password_needs_rehash() when the user logs in and rehash the password as necessary.

If you've split off the algorithm and options indicators and hard coded them - how do you upgrade*? Just changing them means nobody with an old hash can log in. And you can't generate a new hash until the user logs in, so you need to maintain that mapping of algorithm+options to hashes somewhere...

Somewhere like a database.

Store the entire string.


* If you don't upgrade and instead rely on security through obscurity then an attacker only needs to determine the method you used once in order to have everything open right up. I'm not even going to consider this as an option.

user3942918
  • 25,539
  • 11
  • 55
  • 67
  • I do think it makes it a bit harder if you write something like $2$10$ an attacker instantly knows it's blowfish, if you don't use that he/she needs to find it out before he can start.... aswell as you stated upgrading would be harder yes it is, as if you increase the cost you'd either need to add something in your own script to check for both the old and new version(s) or you have to change all rows... Both has it's pro and cons.... – Mike M. Dec 22 '14 at 03:57
  • I dont understand why it will still be virtually impossible to crack the password. The attacker just needs some time now and he will be able to get the passwords by bruteforce. Thanks – akki Dec 22 '14 at 05:12
  • @PaulCrovella Thank you very much. I didn't know that the "some time" I was worrying of would come out to be "many many years". That makes the point clear. Thank you once again. – akki Dec 22 '14 at 12:09
  • @PaulCrovella As a matter of knowledge are there any calculations we can do to prove that point (time taken would be many years) or is it just a conclusion given in some document as theory. Just curious. Thanks – akki Dec 22 '14 at 12:09
  • @PaulCrovella Thanks. Maybe I need to read more even to understand this stuff. – akki Dec 23 '14 at 15:13