我在MySQL中创建了一个名为password_salt_c
的列
我想为数据库中的每条记录设置一个随机的、16个字符的字母数字字符串。
有21.5万条记录。我试着用PHP做这件事,但它耗尽了服务器上所有的内存。
如何在MySQL中做到这一点?
不清楚您实际想要解决的问题是什么。(我的回答故意忽略了要填充的列的名称,并忽略了您所问问题的上下文。)
如果我需要将"一个随机的、16个字符的字母数字字符串"一次性分配给表中所有行的一列,我可能会这样做:
UPDATE mytable SET mycol =
CONCAT(SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
,SUBSTR('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',FLOOR(1.0+RAND()*62),1)
)
请注意,表达式FLOOR(1.0+RAND()*62)
旨在返回1到62范围内的伪随机整数。它被用作SUBSTR
函数的参数,用于返回单个字母数字字符。找出16个重复,将结果连接起来。。。瞧。。。伪随机的16个字符的字母数字字符串。
请不要尝试自己进行安全编程。如果你犯了一点点错误,很难做到正确,坏人也很容易破解。如果你正在生成自己的大量伪随机数集合,那么很容易犯系统性错误。
相反,看看PHP函数password_hash和password_verify。
这些函数没有存储单独的salt字段(正如您建议的那样),而是遵循将salt包含在哈希密码字符串中的约定。CCD_ 4遵循随机化盐的加密最佳实践。
因此,当用户提供一个新的明文密码(更改或设置密码)时,您可以这样做:
$hashed_password = password_hash ( $plaintext, PASSWORD_DEFAULT );
unset ( $plaintext );
您应该将$hashed_password
字符串存储在数据库的varchar(255)列中。该函数生成一个随机salt,然后将其与明文密码一起使用以生成哈希密码,然后将salt和哈希密码存储在一起。通常,它会按顺序运行哈希函数十次。
(我使用unset()
函数是出于谨慎,以避免将明文密码的副本保存在RAM中的时间过长。)
然后,稍后当用户出示密码以获得访问权限时,您可以这样做:
if (password_verify( $plaintext, $hashed_password )) {
/* the password is correct, grant access */
unset( $plaintext );
/* do what the user wanted to do. */
}
else {
/* the password did not match */
}