我用盐创造了盐; MD5(兰特(0,10000000)); (可能有更好的方法吗?)
似乎没有可能在MYSQL中使文本字段唯一。那么如何检查盐是否已用于以前的用户?
或者我应该根据当前日期/时间生成盐?因为2个用户不可能在完全相同的时间注册正确吗?
答案 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;