3

I'm working on a big project's registration system.

After successful signup, the server generates some activation key, adds it to user's row and sends it to user by email. Using some password generator class for this purpose.

The question is (I know that it sounds abstract but I just wonder), how to avoid duplicate pass generation? I mean, is there any chance that in future generator can create the activation key that already exists in db table? Should I check for duplication after key generation?

Tural Ali
  • 22,202
  • 18
  • 80
  • 129
  • Unless you're using some insanely complicated key generator that requires a Top500 supercomputer to make the key, it should trivial to generate a key and check the db if it's been generated before. – Marc B Nov 11 '11 at 22:18
  • Of course you run out of unique values sooner or later, but this doesn't matter since these are initial values and random, therfore quite secure. In fact we can't tell you how likely your algorith is to produce duplicates, because we don't know it at all. -- If you need to assert a value is not a duplicate you can test it for uniqueness, or use some random string plus timestamp. – Smamatti Nov 11 '11 at 22:21

5 Answers5

3

I would recommend using the Text_Password package from PEAR. Don't try to reinvent this wheel.

Don't force passwords to be strictly unique. It's actually less secure to have that enforcement. Consider that if I try to set my password to xyzzy and the site tells me I can't, that means now I know some account is using xyzzy as a password. I just have to try that password on all accounts until I find which one.

Don't use a hash digest as a generated password. Your users don't want to type in a hex string of 32 character (or longer). I have had the experience of coding a secure software activation key package in 2001, using PKI and MD5 hashes. But no one would use it because the keys were too long.

Do use a hash digest and salt to store passwords. Read this article by our fearless leader: You're Probably Storing Passwords Incorrectly.

See also my answers to a few other password-related questions:

Community
  • 1
  • 1
Bill Karwin
  • 538,548
  • 86
  • 673
  • 828
  • Thx for fast reply, sir. Is this code secure enough? md5(uniqid(mt_rand(), true)); – Tural Ali Nov 11 '11 at 22:27
  • and one more thing, how long will be this key md5(uniqid(mt_rand(), true));? Which type and length should I select for database column? – Tural Ali Nov 11 '11 at 22:34
  • Am I missing something? I don't think he's generating a password. He's generating activation keys. (Text_Password can still be used for this though.) – simshaun Nov 11 '11 at 23:23
  • Yeah, it's not an exact comparison, but they are similar enough that I think the best practices for password management are relevant. – Bill Karwin Nov 12 '11 at 00:09
2

Try out uniqid().

simshaun
  • 21,263
  • 1
  • 57
  • 73
1

Using a hash algorithm like SHA or Whirlpool with a unique input (like the users' unique username) will result in a hash that has an expected collision rate of 0.

I wouldn't roll my own algorithm for this. uniqid() or md5(), as mentioned, are guaranteed solutions.

rockerest
  • 10,412
  • 3
  • 37
  • 67
  • `uniqid` is guaranteed, within the scope of your PHP installation, to generate a unique id, so theoretically, `uniqid` is better. However, in practice, both are probably approximately the same. *edit* I would say that code is "secure," but in this context, security isn't really a factor. It will generate a unique result, but it's how you use it that makes it secure. – rockerest Nov 11 '11 at 22:30
  • and one more thing, how long will be this key md5(uniqid(mt_rand(), true));? Which type and length should I select for database column? – Tural Ali Nov 11 '11 at 22:34
  • `md5()` hashes are 128 bits long. You can use `char(128)` if you choose to use `md5()`. See [MD5](http://en.wikipedia.org/wiki/MD5). – rockerest Nov 11 '11 at 22:58
  • 1
    @rockerest: You don't need 128 characters to store 128 bits. It only requires 32 hex digits, or 16 binary bytes. – Bill Karwin Nov 11 '11 at 23:02
0

You could use the time, but it won't be "random" you'd have to add some randomness to it...

$key = md5(time());
Saad Imran.
  • 4,480
  • 2
  • 23
  • 33
  • md5 is not collision safe and your solution will actually generate the same activation key for some simultaneous registrations. – Narcis Radu Nov 11 '11 at 22:23
  • and one more thing, how long will be this key md5(uniqid(mt_rand(), true));? Which type and length should I select for database column? – Tural Ali Nov 11 '11 at 22:35
  • md5 returns a 32-length string, so varchar(32) is what you need for the table column – Narcis Radu Nov 11 '11 at 22:55
0

Use GUID as your registration key, as it is always unique and generated by system

S.M.
  • 71
  • 7