md5(uniqid) makes sense for random unique tokens?

2019-01-21 04:52发布

I want to create a token generator that generates tokens that cannot be guessed by the user and that are still unique (to be used for password resets and confirmation codes).

I often see this code; does it make sense?

md5(uniqid(rand(), true));

According to a comment uniqid($prefix, $moreEntopy = true) yields

first 8 hex chars = Unixtime, last 5 hex chars = microseconds.

I don't know how the $prefix-parameter is handled..

So if you don't set the $moreEntopy flag to true, it gives a predictable outcome.


QUESTION: But if we use uniqid with $moreEntopy, what does hashing it with md5 buy us? Is it better than:

md5(mt_rand())

edit1: I will store this token in an database column with a unique index, so I will detect columns. Might be of interest/

8条回答
女痞
2楼-- · 2019-01-21 05:45

I know the question is old, but it shows up in Google, so...

As others said, rand(), mt_rand() or uniqid() will not guarantee you uniqueness... even openssl_random_pseudo_bytes() should not be used, since it uses deprecated features of OpenSSL.

What you should use to generate random hash (same as md5) is random_bytes() (introduced in PHP7). To generate hash with same length as MD5:

bin2hex(random_bytes(16));

If you are using PHP 5.x you can get this function by including random_compat library.

查看更多
男人必须洒脱
3楼-- · 2019-01-21 05:45

First, the scope of this kind of procedure is to create a key/hash/code, that will be unique for one given database. It is impossible to create something unique for the whole world at a given moment. That being said, you should create a plain, visible string, using a custom alphabet, and checking the created code against your database (table). If that string is unique, then you apply a md5() to it and that can't be guessed by anyone or any script. I know that if you dig deep into the theory of cryptographic generation you can find a lot of explanation about this kind of code generation, but when you put it to real usage it's really not that complicated.

Here's the code I use to generate a simple 10 digit unique code.

$alphabet = "aA1!bB2@cC3#dD5%eE6^fF7&gG8*hH9(iI0)jJ4-kK=+lL[mM]nN{oO}pP\qQ/rR,sS.tT?uUvV>xX~yY|zZ`wW$";
$code = '';
$alplhaLenght = strlen($alphabet )-1;
for ($i = 1; $i <= 10; $i++) {
    $n = rand(1, $alplhaLenght );
    $code .= $alphabet [$n];
}

And here are some generated codes, although you can run it yourself to see it work:

SpQ0T0tyO%
Uwn[MU][.
D|[ROt+Cd@
O6I|w38TRe

Of course, there can be a lot of "improvements" that can be applied to it, to make it more "complicated", but if you apply a md5() to this, it'll become, let's say "unguessable" . :)

查看更多
登录 后发表回答