Why should I hash a random number when generating a secret?

3k Views Asked by At

Lots of code does something like this to generate some kind of secret:

sha1(random())

Why not simply use a random number? I realize that in the past, some OS random generators weren't so great, but I'm not sure that's still true, and even if it were, how does sha1'ing it make it better?

3

There are 3 best solutions below

0
On BEST ANSWER

I suspect that most often the hash function is misused as encoding function. One needs an alphanumeric code of a certain length, and the hash provides such a string. It's easy and it looks unpredictable.

It is easy to forget, that the random part of md5(random()) are not the 32 hex characters of the md5, instead there will be only as many possible results as the random() function delivers. If one knows how the random function works, one could precalculate a range of possible values.

The code would be more random (better entrophy), if you really used the random source of the OS, and request as many bytes as seems necessary. Those bytes you can then encode with a function like base64_encode(). For tokens, a base62 encoding would be ideal, because it is very compact and doesn't return special characters, though it's a bit hard to implement.

To answer your question: A random number would be better, but it has to be "really" random. If you use it as alphanumberic numbers with only '0'-'9', then your token will be long, it can be shortened with an encoding function.

11
On

You wouldn't want to use a random number instead of a hash, because then it becomes easier for an attacker to guess your source and create his own "secret" (especially if you use the system clock, never do that. See Is using microtime() to generate password-reset tokens bad practice). A truly random number is not any better from a randomization standpoint than a hash of a random number but it obscures the pattern such that a human would not be able to recognize any pattern of changes (such as a seed value). Additionally, it does enhance security because a brute force attack takes much longer when the attacker must hash each attempt before submitting. This is especially true with a strong hash like SHA-256. The amount of computational time required for a brute force attack increases significantly when processor intensive operations are required for each submission. This is the reason that Linux went from storing password hashes as MD5 to SHA.

Additionally, SHAs and other hashes have some mathematical benefits that are good for security. Firstly, they always output the same length, regardless of the input length. Secondly, a small change in the input results in a large change in the output, and for a small change in the output, the corresponding input that would be required to obtain that output would differ much more than the previous input. This makes it really hard for an attacker to generate the hash they want by selectively feeding input, and it makes it virtually impossible for two similar inputs to result in the same or even very close outputs.

This is a deep topic that can have an entire textbook written about it, but these are just some high level reasons.

0
On

If you're generating a secret, you should use a cryptographically secure random or pseudo-random number generator. Hashing a non-cryptograpically secure random number is a form of security by obscurity, not a real security measure.

It adds a step to figuring out the secret, which is probably why it's done, but it doesn't make the secret safe.