我希望使用PHP将安全用户密码存储在MySQL数据库中。
如何让它变得更好?
我的班级:
private static $algo = '$2a';
private static $cost = '$10';
private static $pepper = 'eMI8MHpEByw/M4c9o7sN3d';
public static function generateSalt($length) {
$randomBinaryString = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
$randomEncodedString = str_replace('+', '.', base64_encode($randomBinaryString));
return substr($randomEncodedString, 0, $length);
}
public static function generateHash($password) {
if (!defined('CRYPT_BLOWFISH'))
die('The CRYPT_BLOWFISH algorithm is required (PHP 5.3).');
$password = hash_hmac('sha256', $password, self::$pepper, false);
return crypt($password, self::$algo . self::$cost . '$' . self::generateSalt(22));
}
public static function checkPassword($hash, $password) {
$salt = substr($hash, 0, 29);
$password = hash_hmac('sha256', $password, self::$pepper, false);
$new_hash = crypt($password, $salt);
return ($hash == $new_hash);
}
答案 0 :(得分:3)
使用this回答的建议(对于PHP> = 5.5)或以下类。感谢martinstoeckli指出password_hash
函数。我阅读了代码,password_hash
中唯一可以看到的不同之处是错误检查和操作系统DEV_URANDOM
用法生成更随机的盐。
class PassHash {
public static function rand_str($length) {
$chars = "0123456789./qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
//only allowed chars in the blowfish salt.
$size = strlen($chars);
$str = "";
for ($i = 0; $i < $length; $i++)
$str .= $chars[rand(0, $size - 1)]; // hello zend and C.
return $str;
}
public static function hash($input) {
return crypt($input, "$2y$13$" . self::rand_str(22));
// 2y is an exploit fix, and an improvement over 2a. Only available in 5.4.0+
}
public static function hash_weak($input) {
return crypt($input, "$2a$13$" . self::rand_str(22)); }
// legacy support, Add exception handling and fall back to <= 5.3.0
public static function compare($input, $hash) {
return (crypt($input, $hash) === $hash);
}
}
这是我一直用的东西。建议也是PHPass。它经过了试验和测试。
<小时/> 这个脚本中唯一的缺点是我从rand()
生成随机数,而不是来自操作系统的源,但这很容易改变。
此外,没有理由在bcrypt之上使用SHA256
哈希。 SHA256
很弱,可以用相对较少的努力打破 3 。
此外,散列密码是必不可少的做法,但为了真正的安全性,通过至少John the Ripper的wordlist 1 运行所有输入删除最常用的密码并通知用户使用不同的密码。由于密码非常弱,所以Wordlists的使用效率远高于任何暴力。
<小时/> 最后, 不强制用户使用符号,大写和数字,强制他们使用长密码 2 。< p>当涉及到强制密码时,长度就是一切(没有幽默意图)。除非编辑配置,否则几乎所有预设的破解者都将被设置为不超过12个字符。如果您在密码上看到一个“最大长度”的网站,请确保永远不要在那里重复使用密码,因为它们没有任何安全性 4 。
<小时/> 1.任意选择饼干;选择你发现最好的工作