1

I have the following snippet where I am constructing a string to send out to the user as an email confirmation code:

$confirmation_code = $user_id . time() . date('d-m-Y',time());
$confirmation_code = sha1($confirmation_code);

Is there any chance of $confirmation_code being duplicated at any step?

NOTE: Please remember that $user_id is unique for each user

Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
Rashid Farooq
  • 365
  • 5
  • 17
  • Take a look at this related post: http://security.stackexchange.com/questions/29071/will-sha1-of-email-addresses-always-be-unique#29073 – Aiias Mar 24 '13 at 08:20
  • please consider [this note](http://www.php.net/manual/en/faq.passwords.php#faq.passwords.fasthash) also –  Mar 24 '13 at 08:23

2 Answers2

1

Given that $user_id is unique for each user, this should (in theory) mean that your confirmation codes should never clash (be "un-unique")

However, in reality, SHA1 hashes can clash (see this MSDN blog article for more info).

Therefore if the reason you're asking this question is so you can decided whether or not to make the column UNIQUE in a database, don't.

Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
1

Yes, the code should be unique, unless you're generating more than one per user per second. It's also terrifically predictable. If an attacker knows the id of a user and the rough time of when the code is being generated, it's trivial to guess the code. If the attacker is allowed an unlimited number of guesses, even the rough time doesn't really matter, as he could easily try all valid codes for the last couple of years.

You should really generate a (pseudo) random code instead of a code based on rather static data. On Linux, just read from /dev/random:

$code = bin2hex(file_get_contents('/dev/random', false, null, -1, 32));
                                                                  ^^
                                                          desired length/2
deceze
  • 510,633
  • 85
  • 743
  • 889