php – 什么是密码强度,足以与password_hash函数一起使用?

前端之家收集整理的这篇文章主要介绍了php – 什么是密码强度,足以与password_hash函数一起使用?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
据我了解,新 PHP password hashing extension(或一般的bcrypt)最重要的功能之一是算法的速度,这大大减慢了暴力攻击方法.

但它仍然以某种速度运行,肯定足以进行字典攻击和强制弱密码,[据说]短于六个字母数字字符.

所以我想知道,它的速度肯定很慢,特别是哪个密码强度被认为是安全的.
“尽可能强大”并不是一个答案,因为密码强度始终是安全性和可用性之间的权衡 – 所以,我正在寻找可以被认为是安全的甚至是未来证明的最小强度.

请注意我是一个练习者 – 因此,基于具体数字的某些答案比长期和多风的理论推理更为可取,并且结论不确定.

为了澄清一点,最糟糕的情况是:用户数据库被盗,有人会尝试破译密码.由于强盐,彩虹桌不是一种选择.
因此,唯一剩下的向量是字典攻击和暴力.假设我们为用户提供预生成的密码,消除字典攻击.这就是密码强度是我唯一关注的原因.

更新:
我好像不太清楚.对我来说,这个问题非常实用,而且相当负责任.非常重要.

如果没有确定足够的密码强度,可以质疑这种新算法的使用.如果密码仍然不安全,为什么还要用好算法?所以 – 我坚信 – 除了建议使用新的哈希算法外,还应始终建议最小密码强度.我想知道.

换句话说,如果存在关于一部分的特定确定性 – 算法(“使用这一部分,而不是其他部分!”) – 显然应该确定另一部分 – 密码强度,可以用相同级别的权限说出.否则最弱的部分将破坏最强的部分.

我不确定我是否清楚地理解你的问题,但我只关注密码强度以及它如何影响蛮力攻击.

But still it runs at some speed,surely enough for the dictionary attack and to brute-force weak passwords,[supposedly] shorter than six alphanumeric characters.

介绍

暂时忘记哈希算法(md5,sha,pbkdf2 bcrypt,scrypt等)并且首先关注Password Strength

密码强度Wiki

这是衡量密码抵御猜测和暴力攻击的有效性的指标.以其通常的形式,它估计有多少次试验无法直接访问密码的攻击者平均需要正确猜测它.

它可以简单地计算为:

熵由H = Llog2N给出,其中L是密码的长度,N是字母表的大小,并且通常以比特来度量.

哈希函数

password_hash默认情况下使用[bcrypt] [4]并且足够用于密码,但是有更好的选择,例如PBKDF2scrypt,有关我的意思的更多信息,请参阅How To Safely Store A Password

使用oclHashcat,我们估计以下内容

+--------+-----------+----------------+
|  HASH  | ESTIMATE  |     BITS/S     |
+--------+-----------+----------------+
| MD5    | 10742M    | 90110427136    |
| BCRYPT | 31M       | 260046848      |
+--------+-----------+----------------+

请注意,这是一个估计值,可能会因硬件容量而异

有了这些信息,我们可以安全地计算出我们需要多长时间来强制使用不同的密码

PHP中计算熵

$passwords = array(
        "1234","F2A1CC","password","PaSSworD","P4ssw0Rd97","p#aSS*Word14","Dance With Me Tonight" 
);

print("PASSWORD\tLENGTH\tENTROPY\tTIME MD5\tTIME BCRYPT\n");

foreach($passwords as $password ){

    printf("%s\t%s\t%s\t%s\t%s\n",$password,strlen($password),$entropy = calculateEntropy($password),totalTime($entropy,"90110427136"),// Check with MD5
        totalTime($entropy,"260046848")        // Check with BCrypt
    );
}

产量

+-----------------------+--------+---------+------------+----------------+
|       PASSWORD        | LENGTH | ENTROPY |  TIME MD5  |  TIME BCRYPT   |
+-----------------------+--------+---------+------------+----------------+
| 1234                  |      4 |  13.29  | 1min       | 1min           |
| F2A1CC                |      6 |  24.00  | 1min       | 1min           |
| password              |      8 |  37.60  | 1min       | 1min           |
| PaSSworD              |      8 |  45.60  | 1min       | 1day+          |
| P4ssw0Rd97            |     10 |  59.54  | 2mo+       | 71yr+          |
| p#aSS*Word14          |     12 |  75.86  | 13,479yr+  | 4yr+           |
| Dance With Me Tonight |     21 |  120.29 | 474,250yr+ | 164,335,595yr+ |
+-----------------------+--------+---------+------------+----------------+

Output Converted using csv2table

密码破解程序的CUDA / OpenCL实现可以利用GPU中可用的大量并行性,在billions of candidate passwords a second达到峰值.

让我们估算我们可以在非常快的系统上并行执行921600M c / s

T = 966367641600 * 8   
T = 7,730,941,132,800  // bits/sec

运用

foreach($passwords as $password ){  
    printf("%s\t%s\t%s\t%s\n","7730941132800")        // Check with Hash
    );
}

产量

+-----------------------+---------+---------+----------+
|       PASSWORD        | LENGTH  | ENTROPY |   TIME   |
+-----------------------+---------+---------+----------+
| 1234                  |       4 | 13.29   | 1min     |
| F2A1CC                |       6 | 24.00   | 1min     |
| password              |       8 | 37.60   | 1min     |
| PaSSworD              |       8 | 45.60   | 1min     |
| P4ssw0Rd97            |      10 | 59.54   | 20hr+    |
| p#aSS*Word14          |      12 | 75.86   | 157yr+   |
| Dance With Me Tonight |      21 | 120.29  | 5,527yr+ |
+-----------------------+---------+---------+----------+

正如你所看到的那样,要打破一个像样的12位还需要一段时间.

使用的功能

// Calculate Password entropy
// Uses H = L Log2 N
// where L is the length of the password and
// N is the size of the alphabet,and it is usually measured in bits
function calculateEntropy($password) {

    // See http://en.wikipedia.org/wiki/Password_strength
    // Entropy per symbol for different symbol sets
    // Missing All extended ASCII printable characters
    // Missing Diceware word list

    // TODO
    // Larger Character Set
    // '/[\!"#$%&\'\(\)\*\+,\-.\/:;<\=>\?\@\[\]^_`\{|\}~]+/' => 32,$cases = array(
            "/\s+/" => 1,// Arabic numerals (0–9) (e.g. PIN)
            "/[0-9]+/" => 10,// Arabic numerals (0–9) (e.g. PIN)
            "/[a-z]+/" => 26,// Case insensitive Latin alphabet (a-z)
            "/[A-Z]+/" => 26,// Case insensitive Latin alphabet (A-Z)
            '/[\!\@#$%\?\&\*\(\)_\-\+=~:;.]+/i' => 18  // Other Character
        );

    $L = strlen($password); // Length of password
    $N = 0; // Character Set

    foreach($cases as $regex => $value ){
        if (preg_match($regex,$password)){
            $N += $value;
        }
    }

    // Don't confuse hexadecimal for alpha numeric characters
    // hexadecimal numerals (0–9,A-F) (e.g. WEP keys)
    if (ctype_xdigit($password)){
        $N = 16;
    }

    // Fix pure number cases that might have been changed by hexadecimal
    // Arabic numerals (0–9) (e.g. PIN)
    if (ctype_digit($password)){
        $N = 10;
    }

    // Using H = L Log2N
    // See http://en.wikipedia.org/wiki/Password_strength
    // Random passwords entropy
    $H = $L * log($N,2);
    return number_format($H,2);
}

// Claculate Total time it would take
// Using Entropy & froce / s
function totalTime($entropy,$force) {
    bcscale(0);

    // Total Base on entorpy 2^H
    $total = bcpow(2,$entropy);

    // Time Taken per sec on Force
    $ss = bcdiv($total,$force);

    $time = "";
    $parts = [];

    $parts['yr'] = bcdiv($ss,"31104000");
    $parts['mo'] = bcdiv(bcmod($ss,31104000),2592000);
    $parts['day'] = bcdiv(bcmod($ss,2592000),86400);
    $parts['hr'] = bcdiv(bcmod($ss,86400),3600);

    // Clean Year
    // Can really generate large numbers

    $suffix = "";
    $yr = $parts['yr'];
    if (!empty($yr)){
        if (bccomp($yr,"1000000") > 0){
            $parts['yr'] = bcdiv($yr,"1000000"); // Million
            $year = " million ";
        }

        if (bccomp($yr,"1000000000") > 0){
            $parts['yr'] = bcdiv($yr,"1000000000"); // Billion
            $year = " billion ";
        }

        if (bccomp($yr,"1000000000000") > 0){
            $parts['yr'] = bcdiv($yr,"1000000000000"); // Trillion
            $year = " trillion ";
        }
    }

    foreach($parts as $t => $v ){
        if (empty($v)){
            continue;
        }
        $time .= number_format($v,0) . $suffix . $t . "+";
        break;
    }

    return empty($time) ? "1min" : $time;
}

误解

你是对的密码长度很重要,所以密码的熵.大多数建议建议用户使用use bcrypt,密码复杂性等,而不了解密码强度

但事实是最简单的密码往往是最强的.

Source | Related blog post

So I want to know,how it’s certainly slow,and,particularly – which password strength considered safe to be used with.


Source

绝对不是6个字母:)

>< 28位=非常弱;可能会阻止家人
> 28 – 35位=弱;应该阻止大多数人,通常有利于桌面登录密码
> 36 – 59位=合理;相当安全的网络和公司密码密码
> 60 – 127位=强;可以很好地保护财务信息
> 128位=非常强;经常矫枉过正

结论

以下是您可能会看到的一些很好的参考资料

> The Rainbow Table Is Dead
> oclHashcat
> How To Safely Store A Password
> Don’t use bcrypt
> Password Entropy
> Password Strength/Entropy: Characters vs. Words
> HOW MUCH ENTROPY IN THAT PASSWORD?
> Kolmogorov complexity

猜你在找的PHP相关文章