我正在开发一个项目,在保存密码等方面需要一个非常先进的安全系统。所以我的问题是,这种方法是否足够安全地保存密码?
这是我编程的方式:
当用户尝试登录时,我首先检查用户名是否存在。如果是,我使用check()函数检查密码是否正确。
我使用this Bcrypt class加密并检查。
你能告诉我这种加密和验证方式是否适合大型项目?
此致
Jan Willem
答案 0 :(得分:3)
您应该将整个结果存储在数据库中(包括$2a$10
)。如果你正确地做到这一点,这个哈希几乎是不可能蛮力的。省略这条信息只会使你的工作变得更加困难,对于潜在的攻击者而言,这并不会使其变得更加困难。
存储该值可让您查看创建哈希的算法,并随着时间的推移升级。随着硬件变得越来越快,你应该增加算法的工作因素,并且随着更好的算法变得可用(你好scrypt!)你应该升级使用的算法。可行的方法是检查哈希是否是在用户登录时使用最新的创建的。此时,您有机会重新更新明文密码并进行升级。
对旧版本使用PHP的新password_hash
API或password_compat垫片,这些版本经过了充分测试,非常“先进”。
答案 1 :(得分:0)
首先,不要使用bcrypt
。请改用PBKDF2。这将允许您增加进行离线暴力攻击的难度。 [不是说bcrypt不会,它们基本相同,但PBKDF2支持任何散列函数,而不仅仅是Blowfish]
其次,这是你应该怎么做的。
PBKDF2
函数的一部分。现在我想指出系统中的计时攻击。如果您告诉攻击者用户名不存在或者返回错误所需的时间与返回成功所用的时间不同(并且更短),则您可能会发生侧通道攻击。其他信息可以使攻击者更容易枚举您系统上的用户帐户(如果用户名基于电子邮件,则他们现在可以直接对用户进行网络钓鱼攻击)。
答案 2 :(得分:0)
首先,我要感谢你们快速回复,让我们尽可能地破解系统非常重要。
根据您的建议,我制作了以下系统:
当用户注册时,正在创建一个唯一的哈希:
$ unique_hash = hash('sha512',某些已定义的安全密钥(在配置中).openssl_random_pseudo_bytes(50));
第二,创建盐:
$ salt = strtr(base64_encode(openssl_random_pseudo_bytes(50)),'+','。');
在另一个位于另一个数据库中的表中,这两个变量正在合并,只有$ unique_hash存储在users表的users行中。
然后我们创建加密密码,我使用这个函数:
<?php
const COUNT = 8192;
const KEY_LENGTH = 254;
const ALGORITHM = 'sha512';
public static function encrypt($password, $salt, $algorithm = PBKDF2::ALGORITHM, $count = PBKDF2::COUNT, $key_length = PBKDF2::KEY_LENGTH, $raw_output = false) {
$algorithm = strtolower($algorithm);
if(!in_array($algorithm, hash_algos(), true))
die('PBKDF2 ERROR: Invalid hash algorithm.');
if($count <= 0 || $key_length <= 0)
die('PBKDF2 ERROR: Invalid parameters.');
$hash_length = strlen(hash($algorithm, "", true));
$block_count = ceil($key_length / $hash_length);
$output = "";
for($i = 1; $i <= $block_count; $i++)
{
$last = $salt . pack("N", $i);
$last = $xorsum = hash_hmac($algorithm, $last, $password, true);
for ($j = 1; $j < $count; $j++)
$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
$output .= $xorsum;
}
if($raw_output)
return substr($output, 0, $key_length);
else
return bin2hex(substr($output, 0, $key_length));
}
?>
然后我们将此密码存储在默认用户表中。
这就是它。这样安全吗?
Jan Willem