我即将使用这个用户密码系统,但我首先要确保我做得正确。这里是我的测试代码:我在PHP中正确使用CRYPT_BLOWFISH吗?
function generateBlowfishSalt() { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./'; $numChars = strlen($chars); $salt = ''; for($i = 0; $i < 22; ++$i) { $salt .= $chars[mt_rand(0, $numChars - 1)]; } return $salt; } $password = 'foo'; $salt = generateBlowfishSalt(); $hash1 = crypt($password, '$2a$12$' . $salt); $hash2 = crypt($password, $hash1); $compare = ($hash1 == $hash2); printf('password: %s</br>', $password); printf('salt: %s</br>', $salt); printf('hash1: %s</br>', $hash1); printf('hash2: %s</br>', $hash2); printf('compare: ' . $compare);
下面是一个示例输出:
password: foo salt: MYVJ32OqLcMGBar3pUa.0S hash1: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q hash2: $2a$12$MYVJ32OqLcMGBar3pUa.0OTRwv6UX0bcxnSmheKOcqjvqvCrM/p2q compare: 1
我的主要问题是:
我是否正确产生了22字符盐?我见过的一些实现使用
base64_encode()
来生成盐。我需要这样做吗?将数据库中的整个
$hash1
值存储起来并且不存储单独的盐值是否正确,因为$hash1
将有盐分,这就是我需要验证密码的全部内容吗?在PHP
crypt()
文档页面的CRYPT_BLOWFISH
例子有对盐论证后$
(那就是:'$2a$07$usesomesillystringforsalt$'
)。但在所有的例子中,我看到没有人使用尾随$
。它是可选的吗?
感谢
盐不是随机的吗?我使用mt_rand()来生成它。我认为我不需要在crypt()返回的值的顶部存储单独的salt值,因为crypt()返回的值几乎包含了整个盐值。此外,我只需要第一次调用crypt()以返回值以验证密码。 – Ryan
是的,你不需要做任何额外的事情。你正在生成随机盐。我很确定我说过“你在正确地做盐”。只是重申它。你有正确的想法。 – Andy