我准备将它用于用户密码系统,但我首先想确保我正确地使用它。这是我的测试代码:
function generateBlowfishSalt() { $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ./'; $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()
来生成salt。我需要这样做吗?
将整个$hash1
值存储在数据库中并且不存储单独的salt值是正确的,因为$hash1
将包含salt并且这就是验证密码所需的全部内容
在PHP crypt()
文档页面上,CRYPT_BLOWFISH
示例的salt参数的尾随$
(就是这样:'$2a$07$usesomesillystringforsalt$'
)。但是在我看过的所有例子中都没有人使用尾随$
。是可选的吗?
由于
答案 0 :(得分:0)
你正在做正确的盐。只需要随机。随机生成有许多不同的方法。有些人除了日期时间之外还使用它等。此外,较长的盐并不意味着很多,因为它会被切断。它需要一定的长度,至少就crypt()而言。因此,如果一点额外的填充让你感觉更好,那就去吧。
您可以将salt存储在数据库中。起初我很难理解。盐的全部意义只是让彩虹需要更长的时间才能使用大量可能的密码来填写密码。此外,更正它还有助于2个或更多相同的密码,这些密码必然会发生。如果是这样,由于随机盐,散列仍然会有所不同。
至于crypt()继续测试它,直到它看起来和php php for PHP的长度相同,但是看起来是正确的。