问题
I've created a salt using; md5(rand(0,10000000)); (there is probably a better way?)
There doesn't seem to be possible to make a text field unique in MYSQL. So how do I check if the salt has already been used for a previous user?
Or should I generate the salt based on the current date/time? as it is impossible for 2 users to register at exactly the same time correct?
回答1:
For a salt, uniqueness is more important than length and predictability. You assume the attacker has the salt.
A universally unique identifier (UUID) would be best, and there are examples that generate universally unique identifiers on the doc page for the php uniqueid() function. A UUID has the advantage over a random string in that it's human readable and a fixed length, therefore you can store it in a varchar field and use a unique index to ensure there aren't ever duplicates.
Hashing the time with MD5 is a common method to generate unique values because it has a fixed length and is human readable. However, it makes more sense just to generate a fixed length random string and encode it into hex yourself. Hashes aren't designed for uniqueness so much as they're designed not to be reversible. Using a hashing function guarantees collisions, though there will be less collisions with SHA1 than MD5.
The length of the salt is really only a factor because the longer the salt, the more likely it is to be universally unique.
回答2:
MySQL's indexes are length-limited on text fields, they don't go whole-field automatically like they do on char/varchar fields, so there's no practical way to use a 'unique' key on text fields.
But if you're storing hashes generated by MySQL, then you don't need text - the has results are plain-text, so just use a fixed-length char field:
mysql> select length(md5('a')), length(sha1('a'));
+------------------+-------------------+
| length(md5('a')) | length(sha1('a')) |
+------------------+-------------------+
| 32 | 40 |
+------------------+-------------------+
and then you CAN apply a unique constraint to that field.
回答3:
md5() is a broken algorithm and should never be touched.
rand() is slightly broken because it is based on the system clock.
A better method is:
function generateRandomKey()
{
return base_convert(uniqid(mt_rand(), true), 16, 36);
}
Edit: If there is a better way or I'm wrong, please show me your way of doing it. I'm genuinely interested, and would like to know if I'm being insecure.
回答4:
you can use something like http://php.net/manual/en/function.uniqid.php to generate a UUID. or the timestamp is also a good one - maybe even timestamp and ip address or similar.
回答5:
Generate the salt with SHA1 using user id and datetime.
回答6:
You generally dont generate salt strings often. So when you first generate them, you should do a good job. Longer and more random strings are better.
function generateSalt($length = null)
{
if (!is_int($length) || ($length < 1)) $length = 250;
do {
$salt[] = chr(mt_rand(0, 255));
} while (--$length);
return implode('', $salt);
}
update query for new password
update user set salt = :salt, password = sha1(concat(:password, :salt)) where id = :id limit 1;
you can check if the password is correct and get the user data at the same time.
select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;
来源:https://stackoverflow.com/questions/2594328/unique-text-field-in-mysql-and-php