php中的密码/登录系统

时间:2010-04-07 11:26:40

标签: php security hash login

对于php中的登录系统,这将是它如何工作的合适大纲:

用户输入用户名和密码,点击登录按钮。

  1. 检查用户是否存在于数据库中,
  2. 如果是,则检索盐 对于该用户
  3. 哈希密码和 盐(这是做的吗? 客户端还是服务器端?我认为 客户端会更好,但PHP 是服务器端,所以你会怎么做 这个?)
  4. 根据值检查值 数据库,
  5. 如果值匹配则 用户输入了正确的密码 并且他们已登录。

6 个答案:

答案 0 :(得分:6)

  

检查用户是否存在于数据库中,如果确实存在,则检索该用户哈希值的盐密码和盐(这是在客户端还是服务器端完成的?我认为客户端会更好,但php是服务器端那你怎么做呢?)

要记住的重要一点是,从不信任用户,这意味着在身份验证方面,您应该尽可能在服务器端进行。尽可能少地向用户提供信息,并且不要相信任何信息。

关于您的问题,显而易见的一点是,如果您让用户预先计算哈希值,则会涉及更多的数据传输。而不是单个请求和响应,需要3个请求和响应。它还增加了从浏览器到启用JavaScript的浏览器的要求。根据您的受众,许多用户可以禁用JavaScript(通常通过NoScript插件)。

关于安全性,允许用户查看salt不会影响对彩虹表的防御,向他们展示如何组合salt和密码。

无论如何,通过网络界面进行暴力破解都不是 大部分问题,因为希望您每个用户每小时只允许5次(或更多次)登录尝试。知道salt和散列算法根本没有帮助(它只会减少你的服务器负载;))。但是,如果他们拥有数据库并且知道如何将盐和哈希结合起来,那么就可以更容易地进行暴力攻击。

虽然通过默默无闻的安全性并不是真正的防御,但它确实会使您的系统更难破解,因此我建议您不要尝试在客户端进行散列。

答案 1 :(得分:5)

  

检查数据库中是否存在用户,如果确实存在,则检索该用户哈希值的盐密码和盐

没有。这意味着你要两次击中你的数据库。

  

哈希密码和盐(这会在客户端或服务器端完成吗?我认为客户端会更好

没有。散列密码的重点是,如果有人破坏了您的数据库,他们就不能(轻松)找出他们需要发送到您的系统(或其他系统)以便以该用户身份登录的内容。

如果在将密码发送到服务器之前对密码进行哈希处理,则攻击者可以绕过JS并将从数据库中读取的预先设置的密码发送到您的系统。

  1. 用户提交用户名和密码
  2. 使用系统的标准盐对密码进行哈希处理
  3. SELECT some,cols FROM your_users WHERE username =?和密码=?
  4. 计算从数据库返回的行数。

答案 2 :(得分:4)

必须是服务器端

答案 3 :(得分:1)

你走在正确的轨道上,但是让我帮你改进你的系统。

生成一个强随机密钥并将其存储在文档根目录上的文件中:

/home/username/key
/home/username/public_html/login.php

该文件应包含尽可能强度的(伪)随机二进制数据。 512位的随机数据应该还可以。

然后为系统中的每个用户生成一个唯一的salt。这种盐不必比16位随机二进制数据更强。

最后,密码哈希应该是这样的:

hash('sha256', $password . $salt . $key);

哈希算法非常重要。不要使用MD5或SHA-1。使用SHA-2系列,通常是SHA-256或SHA-512。此外,惠而浦是一个不错的选择。

如果你想进一步改进你的系统,你可以反复一遍又一遍地哈希:

public static function hash($algorithm, $data, $iterations = 1, $rawOutput = false)
{
    if ($iterations < 1)
        throw new Exception('There must be at least one iteration.');

    while ($iterations--)
    {
        $data = hash($algorithm, $data, true);
    }

    return ($rawOutput ? (binary) $data : bin2hex($data));
}

答案 4 :(得分:0)

为什么这么多动作?

  1. 检查用户是否存在于数据库中,并使用给定的盐渍哈希密码
  2. 如果是,则检索用户信息
  3. 这就是全部

    如果您正在谈论从客户端到服务器的安全密码传输 - 这是另一个故事,您可以参考架构的HTTP摘要授权说明。简而言之,它是使用存储在服务器端的随机一次性令牌进行客户端密码散列。或者SSL,当然

答案 5 :(得分:0)

大多数,如果不是所有的表单验证都应该在服务器端完成。用户将能够查看所有客户端代码,并且在客户端完成跨数据库的任何验证都会带来大量安全问题。

可能有不同的方法来处理您正在尝试做的事情。这是我会做的:

  1. 如果您希望将用户重定向到某个地方并且需要该页面的用户名,请启动会话
  2. PHP 中散列的一般语法是 hash('nameOfHashFunction', $pswrd . $salt);,您可以将其与您为特定用户存储的散列进行交叉验证。

SHA 系列的最新成员是 SHA-3,它于 2015 年发布。您可以在其 Wikipedia 页面上阅读有关它的更多信息。如果您在阅读本文时 SHA 系列有新成员,我强烈建议您轻松阅读并改用它。

https://en.wikipedia.org/wiki/SHA-2

https://en.wikipedia.org/wiki/SHA-3

相关问题