使用blowfish& amp; PHP存储密码盐&胡椒 [英] PHP storing password with blowfish & salt & pepper

查看:203
本文介绍了使用blowfish& amp; PHP存储密码盐&胡椒的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用PHP将安全的用户密码存储在MySQL数据库中。



如何让它更好?



My Class:

  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));
返回substr($ randomEncodedString,0,$ length);

$ b $ public static function generateHash($ password){
if(!defined('CRYPT_BLOWFISH'))
die('CRYPT_BLOWFISH算法是必需的(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 用法从操作系统生成一个更随机的盐。

  class PassHash {
public static function rand_str($ length){
$ chars =0123456789./qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM;
//只允许在河豚盐中使用字符。
$ size = strlen($ chars);
$ str =;
for($ i = 0; $ i <$ length; $ i ++)
$ str。= $ chars [rand(0,$ size - 1)]; // hello zend和C.
return $ str;

public static hash($ input){
return crypt($ input,$ 2y $ 13 $。self :: rand_str(22));
// 2y是一个漏洞修复程序,比2a更好。仅在5.4.0+
中可用
public static function hash_weak($ input){
return crypt($ input,$ 2a $ 13 $。self :: rand_str(22)) ; }
//遗留支持,添加异常处理并回退到< = 5.3.0
public static function compare($ input,$ hash){
return(crypt($ input, $ hash)=== $ hash);
}
}

这是我一直使用的。建议也是 PHPass 。它已经过尝试和测试。



这个脚本唯一的缺点是我从 rand()生成随机数,而不是来自操作系统的源,但是这很容易改变。



另外,没有真正的理由在bcrypt上使用 SHA256 hashing。 SHA256 很弱,可以用相对小的努力来打破。。

此外,哈希密码是必不可少的实践,但为了真正的安全性,通过至少 John the Ripper 词汇表 1 删除最常见的密码并通知用户使用不同的密码。由于密码非常脆弱,所以使用Wordlists的效率远高于任何暴力破解。



最后, 不强制用户使用符号,大写字母和数字,强制他们使用长密码 2



当涉及暴力破解密码时,长度就是一切(没有幽默意图)。几乎任何预设的黑客将被设置为不超过12个字符,除非配置被编辑。如果您在密码上看到最大长度的网站,请务必不要在那里重复使用密码,因为它们没有任何安全性。



1.饼干的任意选择;选择你最喜欢的工作

2. http://xkcd.com/936/

3.相对而言(这比原来快几个数量级,并且通过默默无闻的技术安全性)

4.我甚至见过银行这样做。密码的最大长度使我切换银行。


I want to store secure user passwords in a MySQL database with PHP.

How can I make it better?

My Class:

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);
}

解决方案

Either use this answer's suggestions (for PHP >= 5.5), or the following class. Thanks to martinstoeckli for pointing out the password_hash functions. I read the code over, and the only different thing in password_hash that I can see is error-checking and DEV_URANDOM usage from the OS to generate a more random salt.

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);
    }
}

It's what I've always used. A suggestion is also PHPass. It's tried and tested.


The only downfall in this script is that I generate random numbers from rand(), and not the source from the OS, but that's easily changed.

Also, there is no real reason to be using SHA256 hashing on top of bcrypt. SHA256 is weak, and can be broken with relatively little effort3.

In addition, hashing passwords is essential practice, but for true security, run all input through at least John the Ripper's wordlist1 to remove the most common passwords and inform a user to use a different password. Wordlists are used far more effectively than any bruteforce due to terribly weak passwords.


And as a final note, do not force your users to use symbols, uppercase and numbers, force them to use a long password2.

Length is everything (no humour intended) when it comes to bruteforcing passwords. Pretty much any preset cracker will be set to not go over 12 characters unless a config is edited. If you ever see a site with a "maximum length" on passwords, make sure to never re-use a password there, because they have no security whatsoever4.


1. Arbitrary choice of cracker; pick what you find to work best
2. http://xkcd.com/936/
3. Comparatively (it's several orders of magnitude faster and is technically security through obscurity)
4. I have even seen banks do this. Having a maximum length on their passwords made me switch banks.

这篇关于使用blowfish&amp; amp; PHP存储密码盐&amp;胡椒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆