Generate a random string (email verification etc), need hash

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

User avatar
batfastad
Forum Contributor
Posts: 433
Joined: Tue Mar 30, 2004 4:24 am
Location: London, UK

Generate a random string (email verification etc), need hash

Post by batfastad »

Hi everyone

I'm working on an e-mail verification system... you know the sort of thing where you have to click a link which has a random string in to activate your account.

I've read a few things now which suggest that you shouldn't use a hash algo on a decent random. Is that correct?

I'm using /dev/urandom to get my random, specifying 32 as the length which I believe gives me 256bit random.
I then convert this to hex to give me a random activation string that's 64 characters in length.

Is that all I need to do, or should I sha256 that random data as well?

It is my understanding that I don't need to hash it as the random is decent... but I could be wrong.
Am I?

Cheers, B
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Re: Generate a random string (email verification etc), need hash

Post by jayshields »

You don't need a random string or a hash for something like this. Just use microtime(). You'll have less chance of a collision.
User avatar
batfastad
Forum Contributor
Posts: 433
Joined: Tue Mar 30, 2004 4:24 am
Location: London, UK

Re: Generate a random string (email verification etc), need hash

Post by batfastad »

So are you saying there's more combinations (lower chance of collision) in a microtime than there for a 256bit random from urandom?
How can that be possible?
User avatar
Apollo
Forum Regular
Posts: 794
Joined: Wed Apr 30, 2008 2:34 am

Re: Generate a random string (email verification etc), need hash

Post by Apollo »

Sounds like overcomplicating things. The following will really do just fine:

Code: Select all

$s = sha1(time().uniqid(mt_rand(),true));
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Generate a random string (email verification etc), need hash

Post by VladSun »

jayshields wrote:You don't need a random string or a hash for something like this. Just use microtime(). You'll have less chance of a collision.
No, it's not an option. One can easily guess its next values - this way bypassing email verification.
Last edited by VladSun on Fri Jan 08, 2010 8:49 am, edited 1 time in total.
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Generate a random string (email verification etc), need hash

Post by VladSun »

batfastad wrote:So are you saying there's more combinations (lower chance of collision) in a microtime than there for a 256bit random from urandom?
How can that be possible?
While I can't say what is the exact chance of collisions for a 256bit pseudo- or not pseudo-random generator, I can tell you (and prove easily) that the chance of having a "collision" of an always-incrementing-number-generator is ZERO. :)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
batfastad
Forum Contributor
Posts: 433
Joined: Tue Mar 30, 2004 4:24 am
Location: London, UK

Re: Generate a random string (email verification etc), need hash

Post by batfastad »

VladSun wrote:No, it's not an option. One can easily guess its next values - this way bypassing email verification.
Yeah that's what I figured. If you do that then surely it's easy for a spammer to bypass the verification as they would know a pretty defined time range of values to try.
VladSun wrote:While I can't say what is the exact chance of collisions for a 256bit pseudo- or not pseudo-random generator, I can tell you (and prove easily) that the chance of having a "collision" of an always-incrementing-number-generator is ZERO.
Excellent point, I didn't think of it that way ;)

But back to the question, if I've got a strong random, do I also need to hash it?
Or is just converting it to hex (rather than raw binary) good enough?
Surely it would only need to be hashed if I wanted to make it one-way encrypted (like a password)

Cheers, B
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Generate a random string (email verification etc), need hash

Post by Eran »

While I can't say what is the exact chance of collisions for a 256bit pseudo- or not pseudo-random generator, I can tell you (and prove easily) that the chance of having a "collision" of an always-incrementing-number-generator is ZERO.
Two users could have clicked at the exact same time and have the same microtime signature. Though the chance of it happening is small, it's not impossible.
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Generate a random string (email verification etc), need hash

Post by VladSun »

pytrin wrote:
While I can't say what is the exact chance of collisions for a 256bit pseudo- or not pseudo-random generator, I can tell you (and prove easily) that the chance of having a "collision" of an always-incrementing-number-generator is ZERO.
Two users could have clicked at the exact same time and have the same microtime signature. Though the chance of it happening is small, it's not impossible.
Yes, that could happen with microtime(), but not with "always-incrementing-number-generator"
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Generate a random string (email verification etc), need hash

Post by Eran »

I understood that microtime() is the number generator in question?
User avatar
timWebUK
Forum Contributor
Posts: 239
Joined: Thu Oct 29, 2009 6:48 am
Location: UK

Re: Generate a random string (email verification etc), need hash

Post by timWebUK »

You could just append the user's email address and hash it. Then it is guaranteed to be unique.

No chance of 'same time collision' then.
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Re: Generate a random string (email verification etc), need hash

Post by jayshields »

Wait a sec, so if I've got 100 people signing up to my website an hour (optimistic!). I'm generating 100 microtimes an hour, right.

So, I say to you, here's my link (a microtime I generated just now with spaces/periods removed) http://www.website.com/activate.php?key ... 1262966470 you can guess someone else's (one of the other 99 people's) link?

I don't even know exactly how microtime() works (I know what it is, but I don't understand why only some data in the micro seconds portion change - probably my PC setup), but even if you could guess the second someone signed up, you have worse than a 1/1000 chance of guessing the exact key.

Ofcourse, you can brute force this pretty easily - this is just a simple approach I'm mentioning. A better approach would to append some random number (or a hash or whatever) to the microtime, and then it would be the best you're going to get in terms of an activation key. There's absolutely no need to use a hashed value for the proper key (like Apollo's).

@timWebUK - not a good idea. So if someone realises that your site is doing that for your activation keys they can just activate any accounts they happen to know the email address for and are unactivated.
User avatar
batfastad
Forum Contributor
Posts: 433
Joined: Tue Mar 30, 2004 4:24 am
Location: London, UK

Re: Generate a random string (email verification etc), need hash

Post by batfastad »

jayshields wrote:I don't even know exactly how microtime() works (I know what it is, but I don't understand why only some data in the micro seconds portion change - probably my PC setup), but even if you could guess the second someone signed up, you have worse than a 1/1000 chance of guessing the exact key.

Ofcourse, you can brute force this pretty easily - this is just a simple approach I'm mentioning. A better approach would to append some random number (or a hash or whatever) to the microtime, and then it would be the best you're going to get in terms of an activation key. There's absolutely no need to use a hashed value for the proper key (like Apollo's).
Yep pretty easy for a spammer to brute force.

Also Apollo's key is hashed... sha1()

That's my question.
If I'm getting strong random from /dev/urandom (way stronger than uniqid(mt_rand()), then I shouldn't need to hash it.
Right?
User avatar
timWebUK
Forum Contributor
Posts: 239
Joined: Thu Oct 29, 2009 6:48 am
Location: UK

Re: Generate a random string (email verification etc), need hash

Post by timWebUK »

jayshields wrote: @timWebUK - not a good idea. So if someone realises that your site is doing that for your activation keys they can just activate any accounts they happen to know the email address for and are unactivated.
The email address would be appended to the microtime (so used in conjunction with) and they hash it.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Generate a random string (email verification etc), need hash

Post by pickle »

Can we keep this on topic folks? ~batfastard has asked his original question 3 times and most of this discussion is about ensuring uniqueness of keys. While it's a valid conversation, it's not helpful to answering the original question.
batfastad wrote:If I'm getting strong random from /dev/urandom (way stronger than uniqid(mt_rand()), then I shouldn't need to hash it.
Right?
Right. Hashing is primarily for obscuring data - which you don't need to do if you've got a random anyway. Hashing doesn't make it any less guessable.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
Post Reply