Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL和php中的唯一文本字段_Php_Mysql_Unique_Salt - Fatal编程技术网

MySQL和php中的唯一文本字段

MySQL和php中的唯一文本字段,php,mysql,unique,salt,Php,Mysql,Unique,Salt,我已经创造了一个盐使用;md5(兰特(010000000));(可能有更好的方法?) 在MYSQL中,似乎不可能使文本字段唯一。那么,我如何检查盐是否已经为以前的用户使用过 或者我应该根据当前日期/时间生成salt吗?因为两个用户不可能同时注册,所以正确吗?md5()是一个错误的算法,永远不要碰它 rand()稍有损坏,因为它基于系统时钟 更好的方法是: function generateRandomKey() { return base_convert(uniqid(mt_rand()

我已经创造了一个盐使用;md5(兰特(010000000));(可能有更好的方法?)

在MYSQL中,似乎不可能使文本字段唯一。那么,我如何检查盐是否已经为以前的用户使用过

或者我应该根据当前日期/时间生成salt吗?因为两个用户不可能同时注册,所以正确吗?

md5()是一个错误的算法,永远不要碰它

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

更好的方法是:

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

编辑:如果有更好的方法或者我错了,请告诉我你的方法。我真的很感兴趣,并且想知道我是否没有安全感。

您可以使用类似的方法生成UUID。或者时间戳也是一个很好的标记-甚至可能是时间戳和ip地址或类似的标记。

使用用户id和日期时间生成salt。

对于salt,唯一性比长度和可预测性更重要。你假设攻击者有盐

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

使用MD5对时间进行散列是生成唯一值的常用方法,因为它具有固定的长度并且是人类可读的。然而,只需生成一个固定长度的随机字符串并自己将其编码为十六进制就更有意义了。散列不是为唯一性而设计的,而是为不可逆而设计的。使用散列函数可以保证冲突,尽管与SHA1的冲突少于MD5


salt的长度实际上只是一个因素,因为salt越长,它越有可能是唯一的。

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

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

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

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

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

function generateSalt($length = null)
{
  if (!is_int($length) || ($length < 1)) $length = 250;
  do {
    $salt[] = chr(mt_rand(0, 255));
  } while (--$length);
  return implode('', $salt);
}
您可以检查密码是否正确,同时获取用户数据

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

另一个被广泛接受的观点是@ledorifier,你发布的链接是关于散列密码,而不是生成随机密码。我指的是“…永远不要被触碰。”生产盐不需要安全,如果攻击者真的想找到创建salt的号码,那就由他们自己来浪费时间。你可以在varchar字段上添加一个唯一的约束-你可以使用它来检查重复的salt。是否有一些奇怪的巧合,碰巧有相同salt的2个用户决定使用相同的密码,then@Jonathan,如果存在具有不同密码摘要的重复salt,我将首先攻击这些帐户,因为它使我有更好的机会找到成功的冲突。两个帐户使用相同的盐和密码,攻击者可以以一个帐户的价格获得两个帐户,但攻击者不会得到任何中断。
select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;