我想存储安全用户密码在MySQL数据库和PHP。
我怎样才能使它更好?
我的课:
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);
}
要么使用这个答案的建议(对于PHP> = 5.5),或下面的类。 由于martinstoeckli您指出的password_hash
功能。 我在阅读代码,并在不同的只有一点password_hash
我能看到的是错误检查和DEV_URANDOM
从OS的使用,以产生更随机的盐。
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()
而不是从OS的源,但是这很容易改变。
另外,有没有真正的理由是使用SHA256
散列的bcrypt的顶部。 SHA256
较弱,可以与相对较少的努力3被打破。
此外,散列密码是必要的做法,但对于真正的安全, 通过至少运行所有输入约翰开膛手的单词表 1,除去最常见的密码,并告知用户使用不同的密码。 生词比任何暴力破解更有效地使用,由于非常弱密码。
而作为最后一点,
不要强迫用户使用符号,大写字母和数字,迫使他们使用长密码 2。
长度是一切(无幽默意),当涉及到暴力破解密码。 几乎任何预设的裂解装置将被设置除非配置被编辑以没过12个字符。 如果你曾经看到有一个密码“最大长度”网站,确保永不再使用密码那里,因为他们没有任何安全4。
1.裂解装置的任意选择; 挑你找到最好的工作
2. http://xkcd.com/936/
3.相比较(这是几个数量级的速度更快,在技术上是安全通过隐藏)
4.我甚至看到银行这样做。 对他们的密码的最大长度让我更换银行。