所以你必须更新数据库中用户的所有密码?如果您 twit 登录脚本,您将无需执行任何操作。看看这个:
将 Md5 密码哈希更新为 BCRYPT 哈希::
$passwordFromDatabase = "0d107d09f5bbe40cade3de5c71e9e9b7"; // md5 hash of "letmein"
$passwordFromForm = $_POST['password']; // $_POST['password'] == "letmein"
if(password_needs_rehash($passwordFromDatabase, PASSWORD_BCRYPT, ["cost" => 12]) && md5($passwordFromForm) === $passwordFromDatabase){
// generate new password
$newPasswordHash = password_hash($passwordFromForm, PASSWORD_BCRYPT, ["cost" => 12]);
// update hash from database - replace old hash $passwordFromDatabase with new hash $newPasswordHash
// after update login user
if(password_veryfi($passwordFromForm, $newPasswordHash)){
// user has logged in successfully and hash was updated
// redirect to user area
}else{
// ups something went wrong Exception
}
}else{
if($password_veryfi($passwordFromForm, $passwordFromDatabase)){
// user password hash from database is already BCRYPTed no need to rehash
// user has logged in successfully
// redirect to user area
}else{
// wrong password
// no access granted - stay where you are
}
}
上面的例子是通用的。代替
... && md5($passwordFromForm) === ...){
您可以使用您对存储密码所做的任何嵌套哈希组合。无论如何,它最终都会成为一个 BCRYP 哈希。下面阅读有关加密和安全性的更多信息,以及如何定义正确的成本参数值来散列用户密码。
慢速算法
当前的标准是使用慢散列算法。PBKDF2、bcrypt 或 scrypt 都将密码和盐作为输入和可配置的工作因子 - 将此工作因子设置为用户在使用服务器硬件登录时接受的最高值。参考
- PBKDF2只是一个迭代的快速散列(即仍然有效地可并行化)。(这是一个可以与不同的基本算法一起使用的方案。使用您在系统中使用的任何算法。)
- Bcrypt需要一些 (4KB) 工作内存,因此在每个处理器缓存少于 4KB 的 GPU 上实现效率较低。
- 除了处理时间之外, Scrypt 还使用(可配置的)大量内存,这使得在 GPU 或定制硬件上并行化的成本非常高,而“普通”计算机通常有足够的 RAM 可用。
好密码
您的密码长度不应少于 8 个字符,并且至少应使用一个:
设置密码 8 字符长,大小写和特殊字符能够创建:6 634 204 312 890 625 组合。但是,如果您的密码是星期,让我们说 6 个字符的小写字母,您只会得到:308,915,776 组合。为了确保您的帐户安全,建议使用超过 12 个字符的密码长度。单击密码组合计数模拟器
破解速度(每年的变化为破解者提供更多的 GPU 处理能力或更强大的云计算)
当您设计密码时,请考虑未来处理能力的提高以及黑客将获得的工具。
该程序 IGHASHGPU v0.90 声称能够在单个 ATI HD5870 GPU 上每秒执行大约 13 亿次 SHA-1 哈希(即超过 2^30)。
假设密码为 40 位熵,这需要 2^10 秒,也就是大约 17 分钟。
一个 44 位熵的密码(就像著名的 XKCD 漫画中的密码)需要 68 分钟(最坏的情况,平均情况是这个的一半)。
在多个 GPU 上并行运行会按比例加快速度。
因此,使用快速哈希进行暴力破解是一种真正的危险,而不是理论上的危险。而且许多密码的熵要低得多,这使得暴力破解更快。参考
解决方案
您可以通过控制成本来自定义算法的速度。成本越高,对密码进行编码和编码所需的时间就越长。最好的目标可能是大约 500 毫升,这使得攻击者很难暴力破解我们的密码。
具有 12 个字符和更长的密码 + 较慢的算法将保证在密码被破解之前暴力破解相当数量的组合。一旦我们有了合适的密码,我们就可以让想要进入我们系统的人的生活变得更加困难,方法是将密码验证过程放慢到会使其变得非常困难和耗时/资源消耗的事情。将成本设置为一个数字,该数字将影响验证用户密码所需的大约 0.5 秒时间。
定制成本价值
由于每个服务器的脚本执行会根据处理能力和流量而有所不同,您怎么知道应该将成本设置多高?
那么您应该衡量验证过程所需的时间并定制适合您的成本。
<?php
/**
* This code will benchmark your server to determine how high of a cost you can
* afford. You want to set the highest cost that you can without slowing down
* you server too much. 8-10 is a good baseline, and more is good if your servers
* are fast enough. The code below aims for ≤ 50 milliseconds stretching time,
* which is a good baseline for systems handling interactive logins.
*/
$timeTarget = 0.50; // 500 milliseconds
$cost = 8; //start to measure from cost = 8
do {
$cost++;
$start = microtime(true);
password_hash("Ajd_hsk-K87&", PASSWORD_BCRYPT, ["cost" => $cost]);
$end = microtime(true);
} while (($end - $start) < $timeTarget);
echo "Appropriate Cost Found: " . $cost . "\n";
?>
参考
上面的函数将返回 X 数量的成本,我们需要使用这些成本来满足我们的安全要求。
Appropriate Cost Found: 13 //this result will be different based on your server machine.
该脚本取自 php 手册并增强处理时间延长 10 倍。在大多数情况下,这通常是安全的方式,但对于管理员和超级管理员登录,我会考虑让它更加耗时(大约 1 秒),因为这些地方对真正的黑客更感兴趣。