PHP存储密码用河豚和椒盐(PHP storing password with blowfish &

2019-08-17 02:21发布

我想存储安全用户密码在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);
}

Answer 1:

要么使用这个答案的建议(对于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.我甚至看到银行这样做。 对他们的密码的最大长度让我更换银行。



文章来源: PHP storing password with blowfish & salt & pepper