0

So essentially the question is, can I use a SHA1 hash to send a verification email to a new user with little chance of duplicate hash?

I want to send a user this email: www.example.com/verify.php?hash=[40 digit sha1 hash]

as opposed to sending them this emai: www.example.com/verify.php?user=123456&hash=[40 digit sha1 hash]

I want to avoid sending a second user parameter.

The hash is created as such:

$verifyHash = sha1[$uid.$email.date('r')];

Where $uid is unique, $email is unique and date('r') is as unique as possible with unix timestamp.

What do you think the chances are of duplicate hashes being created?

fizzy drink
  • 682
  • 8
  • 21

2 Answers2

1

Sufficiently close to zero to ignore.

However, you should additionally add some randomness using mt_rand. The exact time on your server is easy to guess, and email and UID are known to malicious users.

Community
  • 1
  • 1
Phillip
  • 13,448
  • 29
  • 41
  • so add mt_rand to my value? such as `$verifyHash = sha1[$uid.$email.date('r').mt_rand()];` ? – fizzy drink Nov 18 '14 at 17:09
  • would you still add the ?user=12345 parameter to the email? Or do you not foresee someone flooding the verify.php with random sha1 hashes for kicks – fizzy drink Nov 18 '14 at 17:18
  • Yes (adding `mt_rand()` like that is fine), no (it's not necessary to add it) and no (guessing the sha1 hash is extremely unlikely). – Phillip Nov 18 '14 at 17:21
1

Anything less than 12.8 quadrillion blocks, and your odds are 0.00000000000000000000000000000000000000000000000000%.

With 12.8 quadrillion blocks, your odds are 0.00000000000001110223024625156540423631668090820313%. To have 12.8 quadrillion blocks, you need 95 EB with 8 KB chunks, 190 EB with 16 KB chunks, or 290 EB with 24 KB chunks.

Source: http://www.backupcentral.com/mr-backup-blog-mainmenu-47/13-mr-backup-blog/145-de-dupe-hash-collisions.html

See also: https://pthree.org/2014/03/06/the-reality-of-sha1/

In conclusion, yes, it's pretty safe.

That being said, make sure you salt your hash, otherwise they can be reconstructed easily. How random and secure you need that salt to be is up to you.

Curtis Mattoon
  • 4,642
  • 2
  • 27
  • 34
  • would you still add the ?user=12345 parameter to the email? – fizzy drink Nov 18 '14 at 17:18
  • 1
    It depends on how you're doing the lookup in the database. As long as the user ID and hash are positively linked in the DB, you can `SELECT user_id FROM users WHERE verification_hash = :hash` and get the ID that way (since we're assuming the hash is unique). By having two factors in the URL (id/hash, email/hash, etc), it prevents guessing a bunch of hashes and authorizing random users. Is it *needed*? Probably not. Is it useful to include something else? Probably. – Curtis Mattoon Nov 18 '14 at 17:58