2

I was thinking about creating my own hash+salt function, something like sha1(password + md5(login)), then I read here (part 4) that creating it's own hash+salt function is a bad idea, because if the hacker retrieve database content and code he can understand the mecanism behind it.

So I've read the PHP manual for password_hash() and password_verify() functions (appeared with PHP 5.5), first I didn't understand why password_verify() only accept 2 parameters (the real password and its hash), then I saw this in the documentation : the hash contains the algorithm to choose.

So consider I decide to store this generated hash in my database, and a hacker who knows how password_hash() works find my database content, wouldn't be as less secure as creating my own hash+salt function ? Why should I use password_hash()/password_verify()?

Jens Erat
  • 23,816
  • 12
  • 75
  • 96
gokan
  • 121
  • 2
  • 2
    You misunderstood something. "the hacker retrieve database content and code he can understand the mecanism behind it" is not the reason it's a *bad* idea. It's the reason why it is *not a useful* idea. It's a bad idea because you are rolling your own crypto, and unless you have a PhD in both mathematics and computer science, you are not qualified to do this. – Philipp Jul 28 '15 at 15:26
  • 3
    You may want to read that article again more thoroughly. The reason given there for why you shouldn't create your own hash+salt function is _not_ that a hacker could understand the mechanism behind it. – Tilman Schmidt Jul 28 '15 at 15:37
  • Yes it's a misunderstood, I've read the beginning of the sentence "An attacker cannot attack a hash when he doesn't know the algorithm" and I was not well-informed about Kerckhoffs's principle. – gokan Jul 28 '15 at 15:50
  • Need any more information adding to my answer? – SilverlightFox Aug 14 '15 at 18:13

3 Answers3

1

See this for an introduction on password hashing.

That your method ("sha1(password + md5(login))") may be guessed by the attacker is not a problem. Well, it is an indirect problem. Ideally, a "secret algorithm" would protect you even if the said secret algorithm was abysmally weak, because the attacker would still do not know the ends or tails of what you do. Unfortunately, algorithms cannot really be kept secret; and, even more unfortunately, your specific suggestion is abysmally weak.

There are two main problems in your suggestion:

  • The login name is a bad salt, because it does not change when the user changes his password; and also, the same login names may appear in several systems, making it worthwhile to precompute hashes for the login 'admin'.
  • The whole things is way too fast. A basic off-the-shelf GPU will be able to try billions (literally) of passwords per second. Not a lot of user passwords resist for long at that rate.

Then there is the more conceptual issue which is that you are "rolling your own crypto", which is known to be a bad idea. The problem with crypto is that you cannot test for security: there is no way to ascertain that what you produced is secure or not. Functional tests can tell you whether your system works, not whether it resists attacks. To assess the security of a cryptographic algorithm or protocol, the best way (which is not necessarily good, but we have no better) is to publish it and let dozens of cryptographers try to break it for some time (counted in years, because ye cannot rush art). If the algorithm survives 5 years of active attempts, then it is probably good, or at least not trivially weak.

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
0

You've misunderstood the reason why you shouldn't attempt to roll your own password hashing procedure: It's not that knowing the details of the algorythm can lead to someone can understand the mechanism behind it (in fact, it is expected: see Kerechoff's principle), it's that writing good crypto is hard.

As an example, the function you proposed is weak: you're aren't using random salt and aren't stretching your keys, two faults that makes your algorythm vulnerable to brute-force attacks from anyone having access to your database.

Stephane
  • 18,607
  • 3
  • 62
  • 70
0

The security in a hash function is not that the mechanism is unknown - it is that the hash function has been proven over time to be secure. For example, uniform distribution over the keyspace, and has cryptographic properties such as collision resistance, preimage resistance and second preimage resistance. For password hashing, collision resistance and second preimage resistance properties do not matter - it is only preimage resistance that is important:

for essentially all pre-specified outputs, it is computationally infeasible to find any input which hashes to that output

A home grown hash function cannot be demonstrated to have such properties without the eyes of other cryptographers to properly scrutinise your algorithm.

A secure hashing algorithm cannot be reversed if it is used with a salt. The only way an attacker can find out the password from gaining the hash and its salt is by guessing the password. That is, they will hash each guess and find out if it hashes to the same password when the salt is added.

Using password_hash in PHP without the $algo parameter will always use the most secure algorithm at the time. A secure hashing algorithm is slow so that if an attacker manages to get the hashes and salt that they have to wait a long time to run through their password guesses. So a real user logging in has to wait 1 * the slow algorithm, say one second. An attacker trying 10 million password guesses would have to wait 10,000,000 seconds. You should assume they have better hardware than you, so in reality these maths don't hold out - the point is that a slow algorithm will sufficiently slow their attack. The current password_hash algorithm, which is bcrypt, has been proven to be slow without any shortcuts available in order to find whether a given password guess results in the password hash.

SilverlightFox
  • 33,698
  • 6
  • 69
  • 185