12

可能重复:
PHP 密码的安全哈希和盐

我在 stackoverflow 和其他网站上阅读了很多关于网络安全的帖子。例如加盐加密等。而且我有点不明白,所以一个简单的解释会非常有帮助。

这就是我目前所知道的。用户登录输入他的用户名和密码。然后输入经过一个过程。假设用户名和密码组合在一起,例如:

$username = (USERS USERNAME INPUT);
$password = (USERS PASSWORD INPUT);
$userinput = $username . $password;

然后我们加点盐。

$salt1 = "13$13aVc!kd";
$salt2 = "4kr$!vlmeoc";

$salted = $salt1 . $userinput . $salt2;

然后我们对其进行加密。

$encrypted = encrypt($salted);

然后检查数据库,看看它的正确用户是否登录。

这就是它的工作原理吗?但我读过关于蛮力攻击的文章。它猜对了输入值吗?用上面的程序。这不是说明攻击者只需要正确获取 $userinput 信息就可以进入吗?他不需要猜测很长的 $encrypted 字符串是否正确?

注意:假设在这种情况下没有验证码,没有尝试次数限制,没有锁定,除了上面的没有别的。

注意:要温柔我还在学习。

4

5 回答 5

8

如果您排除验证码,请尝试限制、锁定等...然后是的。你只需要暴力破解纯文本字符串。

但是,这确实需要时间——至少,它受到服务器响应登录请求的速率的限制。即使开发者不添加任何防止暴力破解的措施,服务器本身也只能这么快的完成加密+验证的过程,也只能处理这么多的并行请求。

也就是说,这就是为什么重要的是

  • 作为用户,使用强大的、难以暴力破解的密码
  • 作为开发人员,有足够的措施来防止你的登录过程被暴力破解

散列和加盐密码并不是为了防止那些暴力破解自然登录过程的人(还有其他东西可以防止这种情况发生)。相反,它们是为了防止密码存储本身的潜在危害(例如,有人转储数据库的内容)。

散列和加盐都用于降低有权访问存储密码的人检索纯文本字符串的速度,他们需要能够通过自然登录过程(您的站点或其他站点,假设密码是通常在站点之间共享)而不会触发反暴力破解安全措施。

于 2013-01-21T04:50:55.250 回答
2

散列和加盐的想法更多是为了防止有人在数据库本身受到破坏时获取用户密码。如果密码存储为加盐和散列的字符串,攻击者就不能只使用它们来访问另一个站点上的用户帐户。

于 2013-01-21T04:53:05.460 回答
1

密码加密是单向加密(或者更确切地说,它假设在安全站点中)。也就是说,您获取密码并对其进行哈希处理。例如,bcrypt 是当今可接受的标准。

如果它是单向加密,很多人想知道它如何检查密码。但是您只需对用户提交的密码进行哈希处理,并将其与您存储在数据库中的哈希值进行比较。这样,如果您的数据库被盗,攻击者必须更加努力地工作。

仅散列密码的问题很容易被暴力破解或彩虹表。您可以谷歌彩虹表以了解更多信息。但本质上它是一种将这些哈希值转换回密码的方法。

加入盐腌。加盐基本上是在每个密码中添加随机数据。这胜过彩虹表。这意味着受损的数据库将意味着蛮力。如果您使用的是像 bcrypt 这样的哈希系统,那么被攻击者需要花费大量的时间和精力。

说了这么多。最好不要重新发明轮子。如果可以,请使用已知良好的授权系统。

于 2013-01-21T04:53:56.687 回答
0

在这里查看我的答案

当您创建哈希时,您应该为每个条目生成唯一的盐。

于 2013-01-21T05:02:21.810 回答
0

蛮力攻击的一个问题是当您使用 SHA1 或 MD5 等快速加密时。构建这些函数是为了通过算法快速运行密码。相反,您可以使用我不是专家的 Blowfish 方法,但长话短说,它需要比 SHA1 或 MD5 更多的计算来计算返回值。这意味着暴力破解密码可能需要 5 年,由于计算时间的原因,使用 Blowfish 进行哈希处理。

下一个示例是使用 SHA1 和 MD5 制作的,因此它很容易受到暴力攻击,但是 salt 部分应该可以使用:

$salt = md5(microtime().uniqueid());

这将输出一个唯一的 32 个字符的 salt,您将把它与密码放在一起。

$passwod = $_POST['password'];
$hashed_password = sha1($password.$salt);

现在您必须将密码和盐值都存储在数据库中。当你检查用户输入密码时,你会得到盐,并对整个事情进行哈希处理。

$temp_pass = $_POST['temp_pass'];
$salt = //from database;
$database_pass = //hashed pass from database;

$hashed_temp_pass = sha1($temp_pass.$salt);

if(hashed_temp_pass == $database_pass){
//Welcome user!
}
else{
//go away
}
于 2013-01-21T06:43:27.030 回答