MySQL和php中的独特文本字段

时间:2010-04-07 16:50:37

标签: php mysql unique salt

我用盐创造了盐; MD5(兰特(0,10000000)); (可能有更好的方法吗?)

似乎没有可能在MYSQL中使文本字段唯一。那么如何检查盐是否已用于以前的用户?

或者我应该根据当前日期/时间生成盐?因为2个用户不可能在完全相同的时间注册正确吗?

6 个答案:

答案 0 :(得分:1)

对于盐,独特性比长度和可预测性更重要。你认为攻击者有盐。

通用唯一标识符(UUID)最好,并且有一些示例可以在php uniqueid()函数的doc页面上生成通用唯一标识符。 UUID优于随机字符串,因为它具有人类可读性和固定长度,因此您可以将其存储在varchar字段中并使用唯一索引来确保不会出现重复。

使用MD5散列时间是生成唯一值的常用方法,因为它具有固定的长度并且是人类可读的。但是,生成固定长度的随机字符串并将其自身编码为十六进制更有意义。哈希不是为了独特而设计的,因为它们的设计不是可逆的。使用散列函数可以保证冲突,但与SHA1相比,与MD5的冲突会更少。

盐的长度实际上只是一个因素,因为盐越长,它就越有可能是普遍独特的。

答案 1 :(得分:1)

MySQL的索引在文本字段上是长度限制的,它们不会像在char / varchar字段上那样自动进入整个字段,因此没有实际的方法在文本字段上使用“唯一”键。

但是如果你存储由MySQL生成的哈希值,那么你不需要文本 - 结果是纯文本的,所以只需使用一个固定长度的字段:

mysql> select length(md5('a')), length(sha1('a'));
+------------------+-------------------+
| length(md5('a')) | length(sha1('a')) |
+------------------+-------------------+
|               32 |                40 | 
+------------------+-------------------+

然后您可以对该字段应用唯一约束。

答案 2 :(得分:0)

md5()是一个破碎的算法,永远不应该被触及。

rand()略有损坏,因为它基于系统时钟。

更好的方法是:

function generateRandomKey()
{
    return base_convert(uniqid(mt_rand(), true), 16, 36);
}

修改:如果有更好的方法或我错了,请告诉我你这样做的方式。我真的很感兴趣,想知道我是不安全的。

答案 3 :(得分:0)

您可以使用http://php.net/manual/en/function.uniqid.php之类的内容生成UUID。或者时间戳也是一个好的 - 甚至可能是时间戳和IP地址或类似的。

答案 4 :(得分:0)

使用用户ID和日期时间生成SHA1的盐。

答案 5 :(得分:0)

您通常不会生成盐串。所以当你第一次生成它们时,你应该做得很好。更长,更随机的字符串更好。

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 user set salt = :salt, password = sha1(concat(:password, :salt)) where id = :id limit 1;

您可以检查密码是否正确并同时获取用户数据。

select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;