5

I am currently writing a program and part of it involves securely creating password hashes to store in a database and I came across the phpass framework, which seems to be highly recommended. In phpass, they seem to go through great lengths to produce a salt that is as truly random as possible to be used for the hashes (e.g. reading from /dev/urandom).

My question is, what is the benefit of doing this as opposed to simply using uniqid()? Isn't the point simply to make sure that the salts used for the hashes are different from each other rather than random? Wouldn't using a truly random salt actually be worse than using a unique salt since it could potentially produce collisions while uniqid() won't?

Edit: My question wasn't about whether or not "true" randomness exists in computer environments, so maybe I misphrased it a bit, however my question was more along the lines of whether a "more" random salt has any benefit over more uniqueness as a salt.

Mike
  • 23,542
  • 14
  • 76
  • 87
  • 2
    would it go better with http://crypto.stackexchange.com/ ? – Can Poyrazoğlu Aug 13 '11 at 00:39
  • 4
    Physicists disagree on whether the universe is fundamentally deterministic or not. Until that is known, nothing can be considered truly random. Philosophy aside, all random number generating algorithms are pseudorandom. They can be made to seem more random by seeding them with outside entropy, like the temperature of the CPU or sound from a microphone, but they're still not truly random. – Dan Grossman Aug 13 '11 at 00:40
  • 2
    @Dan: I'd say that's the opposite of "philosophy aside"! For all intents and purposes, external entropy sources are completely unpredictable, and are therefore as good as random. – Oliver Charlesworth Aug 13 '11 at 00:42
  • OK updated question. Sorry about that. – Mike Aug 13 '11 at 00:44
  • 4
    @Oli Some people believe the world is fundamentally deterministic, which would mean those sources are perfectly predictable, as is everything else that happens in the universe -- given a known state, you can model all future states. That's the philosophy. "Philosophy aside", meaning "putting that aside" or "ignoring that", then we agreed, you can use outside entropy to make a RNG *more random*, whether it's true randomness or not. – Dan Grossman Aug 13 '11 at 00:45
  • 1
    Dan, I believe this is good enough to be an answer. +1 – Delan Azabani Aug 13 '11 at 00:48
  • given a known state.. that's a bit problematic :) here you can discuss further: http://philosophy.stackexchange.com/ – Karoly Horvath Aug 13 '11 at 00:51
  • @Dan Grossman: I believe you are referring to the 'the universe could just be a computer program' sort of Philosophy. But certain chaotic systems can be non-deterministic in the sense you cannot precisely measure the starting state, and therefore can't predict the final state. – Mitch Wheat Aug 13 '11 at 01:21
  • @Dan Grossman Clever answer, but known physics disagrees with you - especially with measurement of temperature. http://en.wikipedia.org/wiki/Noise_(electronics)#Thermal_noise – Josh Aug 13 '11 at 02:06
  • @Josh That is not a disagreement. You misunderstand the argument. Those that believe the universe is deterministic believe even the motion of electrons is predictable. This is a philosophical argument, not a practical one. I think yi_H's advice should be taken and any further discussion of determinism happen at philosphy.SE. – Dan Grossman Aug 13 '11 at 02:16

4 Answers4

1

I'm trying to find references to some precedents of exploits (and struggling!), but the idea of a cryptographically random salt as opposed to a random value such as produced by uniqid() is to help protect against attacks on the encryption scheme by way of the ciphertext. A salt with a predictable pattern - such as a unique ID - generated by a pseudo-random number generator takes some of that variability out of the ciphertext and of course, in cryptography, unpredictability is what you're looking for.

Certainly if a cryptographically-secure random number generator is available to you in your framework of choice (i.e. RNGCryptoServiceProvider in .NET), you'd opt for this over more predictable patterns. I'll see if I can find some good precedents or white-papers on this.

Troy Hunt
  • 20,345
  • 13
  • 96
  • 151
0

In PHP, the uniqid() function calculates its result based on the current time. This helps ensure that the values are unique because no two times occur twice, however this does not work across multiple servers since it is purely time-based. Using something time-based is bad because the number of different values that can be produced by uniqid() are very limited. Assuming that PHP has been in use for 25 years, this calculates to 7.89e+14 microseconds that have passed and therefore the same number of values for uniqid() would have been produced.

This is a very large number, however assuming that we are able to get a truly random salt, the chance of a collision is actually far less than when using uniqid(). The possible characters that can be used as a salt are:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

That means we have 64 different characters to use for a 22 characters long salt, which calculates to roughly 5.44e+39 different combinations.

So basically, in trying to make something unique, it is actually less unique than it would be if a random source were used.

Mike
  • 23,542
  • 14
  • 76
  • 87
-1

Mike, as I said in my another answer, I wouldn't think this is an issue with salts, but if you are really concerned about true/pseudo randomness, you can use numbers from random.org. See the difference, a and see how to get true random number in PHP.

Tomas
  • 57,621
  • 49
  • 238
  • 373
-9

I think it doesn't matter as the salt must be also stored alongside with the hashed password, so the attacker will get the salt anyway and the attack will be the same, regardless HOW did you generate the salt.

(OT discussion: I argued that I don't see big advantage of using salt for storing passwords - once the attacker gets salt for particular hashed password, he can do dictionary attack anyway ... it will be slower, because the attacker must rehash the dictionary for each password salt, but.. md5() is fast as hell and if the attack takes 5 minutes or half day, what's the real difference... I don't feel much safer with salt than without.)

EDIT - discussion conclusion: salt makes a big difference in time needed to crack the passwords, but don't use md5() for hashing passwords! Use very slow hashing function like bcrypt() or, if you need to use md5(), call it many thousand times!

Tomas
  • 57,621
  • 49
  • 238
  • 373
  • 5
    Not seeing the advantage of a salt is... bad. – deceze Aug 13 '11 at 00:49
  • @deceze... don't see big advantage for storing passwords. I explained my stance in my post, so please argue. – Tomas Aug 13 '11 at 00:52
  • 2
    Salt isn't meant to defend against dictionary attacks. There's very little that can defend against dictionary attacks other than a decent password policy (and enforcement of it). Salt's purpose is to make precomputed hash->password maps (most famously, rainbow tables) infeasible, forcing an attacker to go through a whole bunch more work for each password they want to crack -- assuming, of course, you have that password policy i just mentioned. – cHao Aug 13 '11 at 00:53
  • There's nothing to argue. Salts are a basic ingredient for storing passwords, there are any number of articles and arguments out there about this topic. For example: http://www.openwall.com/articles/PHP-Users-Passwords – deceze Aug 13 '11 at 00:54
  • 1
    The purpose of salts and cryptographic keys is to make the computational effort involved in matching or decoding computationally expensive, not infinitely unknown. – Jared Farrish Aug 13 '11 at 00:56
  • 1
    Salt makes a massive difference and you don't necessarily have to store it alongside the password. By using salt, you defeat simple rainbow attacks. Slower means slower by an order of magnitude. The concept is to make the attack require resources beyond the reasonable scope of your hacker. More here: http://stackoverflow.com/questions/420843/need-some-help-understanding-password-salt – Fenton Aug 13 '11 at 00:56
  • well, guys, thx, but I knew all this... as I said in my post, I don't see BIG advantage, because computing md5() is fast as hell so I don't feel much safer with salt than without... sorry. You're right it will take more time, but if it takes 10 minutes or half day, what's the difference??? – Tomas Aug 13 '11 at 01:04
  • 1
    Well, you're not using MD5 for password hashes either. Precisely because it's fast. If you have to, at least stretch it a few thousand times. There are many techniques that need to be used together to make storing passwords safe (where "safe" means "hard enough for attackers to breach to make it unfeasible"). You're not using any of them because each one individually is not worth it in you opinion? Sorry, but you deserve another downvote for that. – deceze Aug 13 '11 at 01:07
  • that difference is enough to detect the breach, auto-generate new passwords, send them in mail to users, etcetc... all that before someone can actually decrypt passwords. – Karoly Horvath Aug 13 '11 at 01:09
  • 1
    @Tomas, I never said anything about md5 and if you checked the library I mentioned in my question, you would see that it uses bcrypt, which is much slower than md5 and also made purposely slower by increasing the cost parameter accordingly. md5 should not be used for password hashing. – Mike Aug 13 '11 at 01:16
  • @deceze: using md5() 10^n times - good point! That's really a good idea! OK, then it makes sense finally, you persuaded me! – Tomas Aug 13 '11 at 01:20
  • @Tomas Glad I did. But as I said, you're not using MD5 for passwords to begin with. – deceze Aug 13 '11 at 01:24
  • guys, thank you, today I learned something new! Thank you for argueing! Edited my post. Howgh! – Tomas Aug 13 '11 at 01:26
  • guys, Just one more thing - do you agree with the 1st paragraph of the post? – Tomas Aug 13 '11 at 01:27
  • @Tomas I think that first paragraph is not wrong, but maybe a little too simplistic to fully answer the question. Yes, if you have the hash, it's basically irrelevant how you derived it. But, there *may* be other attack vectors that could be made more difficult by having a more unpredictable salt. That's pretty theoretic though and if I could answer this myself I would do so... :o) – deceze Aug 13 '11 at 01:46