我不确定我是否清楚地理解了你的问题,但我只会关注密码强度以及它如何影响暴力攻击。
但它仍然以某种速度运行,对于字典攻击和暴力破解弱密码来说肯定足够了,[据说]短于六个字母数字字符。
介绍
暂时忘记哈希算法(md5、sha、pbkdf2 bcrypt、scrypt 等),以免首先关注密码强度
密码强度 维基
这是衡量密码抵抗猜测和暴力攻击的有效性的指标。在其通常的形式中,它估计没有直接访问密码的攻击者平均需要多少次试验才能正确猜出密码。
它可以简单地计算为:
熵由H=Llog2N
whereL
是密码的长度和N
字母的大小给出,通常以位为单位。
哈希函数
password_hash
默认情况下使用[bcrypt][4]
with 就足够了密码,但有更好的选择,如PBKDF2或scrypt了解更多关于我的意思的信息,请参阅如何安全地存储密码
使用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+ |
+-----------------------+--------+---------+------------+----------------+
使用 csv2table 转换的输出
密码破解器的 CUDA/OpenCL 实现可以利用 GPU 中可用的大量并行性,达到每秒数十亿个候选密码的峰值。
让我们估算一下,我们可以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",
$password,
strlen($password),
$entropy = calculateEntropy($password),
totalTime($entropy, "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;
}
误解
您是对的,密码长度很重要,密码的熵也很重要。大多数建议建议用户在不了解密码强度的情况下使用 bcrypt 、密码复杂性等
但事实是最简单的密码往往是最强的。
来源| 相关博文
所以我想知道,它确实很慢,特别是 - 使用哪种密码强度被认为是安全的。
资源
绝对不是6 letters
:)
- < 28 位 = 非常弱;可能会阻止家庭成员
- 28 - 35 位 = 弱;应该阻止大多数人,通常适用于桌面登录密码
- 36 - 59 位 = 合理;相当安全的网络密码和公司密码
- 60 - 127 位 = 强;可以很好地保护财务信息
- 128+ 位 = 非常强;经常矫枉过正
结论
这里有一些很好的参考资料,你可能会看什么