【发布时间】:2018-01-08 18:31:46
【问题描述】:
在 PHP 中有什么方法可以制作随机的、可变长度的盐以用于散列?假设我想制作一个 16 个字符的长盐 - 我该怎么做?
【问题讨论】:
标签: php salt-creation
在 PHP 中有什么方法可以制作随机的、可变长度的盐以用于散列?假设我想制作一个 16 个字符的长盐 - 我该怎么做?
【问题讨论】:
标签: php salt-creation
编辑:mcrypt 扩展已被弃用。
对于新项目,请查看
random_bytes ( int $length )
和sodium(从 php 7.2 开始)扩展。
如果mcrypt extension 可用,您可以简单地使用mcrypt_create_iv(size, source) 创建盐。
$iv = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
var_dump($iv);
由于“字符串”的每个字节都可以在 0-255 之间的范围内,因此您需要一个二进制安全函数来保存/检索它。
【讨论】:
mcrypt_create_iv 似乎是可行的方法,但 PHP 7.1.0 不再支持。有什么选择吗?谢谢
取决于您的操作系统,例如:
$fh=fopen('/dev/urandom','rb');
$salt=fgets($fh,16);
fclose($fh);
请阅读 random 和 urandom 的行为。
虽然其他人已正确指出 md5 和重复散列存在一些问题,但对于密码(即相对较短的字符串)而言,无论散列算法有多复杂,暴力攻击都需要相同的时间。
C.
【讨论】:
$salt = file_get_contents('/dev/urandom', false, null, 0, 16); :)
这是我找到了一个生成随机字符串的函数:
/* random string */
function rand_string( $length ) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$size = strlen( $chars );
for( $i = 0; $i < $length; $i++ ) {
$str .= $chars[ rand( 0, $size - 1 ) ];
}
return $str;
}
【讨论】:
一个好的盐有两个先决条件:它必须是长的,它必须是随机的。有很多方法可以做到这一点。例如,您可以使用microtime 和rand 的组合,但您可能会更加努力以确保您的盐是独一无二的。
虽然发生冲突的可能性可以忽略不计,但请记住,使用 MD5 或其他容易发生冲突的算法对您的盐进行散列会降低您的盐无缘无故独一无二的可能性。
编辑:用rand() 替换mt_rand()。正如 Michael 所说,它比 rand 更好。
【讨论】:
rand 和 mt_rand() 都不是加密 PRNG。