【问题标题】:Making a password secure确保密码安全
【发布时间】:2017-09-26 18:48:01
【问题描述】:

我目前正在寻找加密和存储用户密码的最佳做法。 目前,我在我的 JSON 配置中存储了一个由 16 个字符组成的“密钥”,并且我总是将这个密钥和密码连接起来以生成一个“安全”密码。

如何更好地处理这种情况?每个密码都有 1 个密钥是否足够安全,还是我应该放弃这种方法以支持良好的 ol' 数据库密码 + 盐存储?

class PasswordHandler
{
    private $_secret_key;

    private $_password;

    public function __construct($password = 'myVeryStrongPasswordThanNoneCouldBreak') {
        $this->_secret_key = 'i36P8JKnyuvaNDah';
        $this->_password   = $password;
        return $this;
    }

    public function processPassword() {
        return hash('sha256', $this->_secret_key . $this->_password);
    }
}

echo (new PasswordHandler)->processPassword();

还有:

  1. 是否足够散列或者我应该加密密码? SHA-256 是否足够强大?
  2. 在处理密码时,哪种散列/加密算法是最佳选择?

亲切的问候!

【问题讨论】:

标签: php security


【解决方案1】:

SHA-256 足够强大吗?

今天可能还可以,但明天就不行了。通用哈希的设计速度很快,这就是为什么它们是密码的错误选择。您想使用一个设计为需要大量计算工作的系统。

在处理密码时,哪种散列/加密算法是最佳选择

唯一你应该在 PHP 中用来散列密码的是password_hash() 和它的伙伴函数password_verify()。如果您使用的是 5.5 之前的 PHP 版本,则可以使用 this compatibility pack

另请注意:

$this->_secret_key = 'i36P8JKnyuvaNDah';

您的密钥不再是秘密。

【讨论】:

  • 这^ 与 7.x 兼容吗?
【解决方案2】:

我会使用 PHP 函数 password_hash 和 bcrypt(加密河豚):source

$encrypted = password_hash("plainpassword", PASSWORD_BCRYPT);

您还可以阅读为什么CRYPT_BLOWFISH is the strongest hash algorithm.

【讨论】:

  • 这篇文章真的很有帮助!谢谢!
【解决方案3】:

查看password_hash() 函数。它为每个密码生成一个动态盐。我认为这更好,因为如果有人找到了密钥,他就可以解密所有密码。

此函数与password_verify($pass_entered, $pass_stored) 一起使用。

【讨论】:

    【解决方案4】:
    密码保护背后的详细故事

    密码

    最简单和最古老的实体身份验证方法是密码,即索赔人拥有的密码。当用户需要访问系统以使用系统资源(登录)时使用密码。每个用户都有一个公开的用户标识和一个私有的密码。我们可以将这种身份验证方案分为两组:固定密码和一次性密码。

    固定密码

    在这个组里,密码是固定的;每次使用相同的密码 使用权。这种方法会受到多种攻击。

    o 窃听。

    Eve 可以在 Alice 输入密码时看到她。作为一种安全措施,大多数系统不会显示用户键入的字符。窃听可以采取更复杂的形式。 Eve 可以监听线路然后截取消息,从而捕获密码供她自己使用。

    o 窃取密码。

    第二种类型的攻击发生在 Eve 试图物理窃取 Alice 的密码时。如果 Alice 不写下 密码;相反,她只是把它记在心里。因此,密码应该非常简单,否则与 Alice 熟悉的东西相关,这会使密码容易受到其他类型的攻击。

    o 访问文件。

    Eve 可以侵入系统并访问 密码被存储。 Eve 可以读取文件并找到 Alice 的密码,甚至 更改。为了防止这种类型的攻击,可以对文件进行读/写保护。但是,大多数系统都需要这种类型的文件才能被公众读取。

    o 猜测。

    Eve 可以登录系统并尝试通过尝试猜测 Alice 的密码 不同的字符组合。如果允许用户选择短密码(几个字符),则密码特别容易受到攻击。如果爱丽丝选择了一些没有想象力的东西,例如她的生日、她孩子的名字或她最喜欢的演员的名字,它也很容易受到攻击。为防止猜测,建议使用较长的随机密码,这不是很明显。但是,使用这种随机密码也可能会产生问题; Alice 可能会将密码存储在某个地方,以免忘记它。这使得密码容易被窃取。

    更安全的方法是将密码的哈希值存储在密码文件中(而不是明文密码)。任何用户都可以读取文件的内容,但是,由于散列函数是单向函数,几乎不可能猜出密码的值。即使 Eve 拥有密码文件,哈希函数也会阻止 Eve 访问系统。但是,也有可能发生另一种类型的攻击,称为字典攻击。在这次攻击中,夏娃有兴趣找到一个通行证—— 字,无论用户 ID 是什么。例如,如果密码是 6 位,Eve 可以创建一个 6 位数字的列表(000000 到 999999),然后对每个数字应用哈希函数;结果是一百万个哈希的列表。然后,她可以获取密码文件并搜索第二列条目以找到匹配项。这可以在 Eve 的私人计算机上进行编程和离线运行。找到匹配项后,Eve 可以上网并使用 访问系统的密码。我们将在第三种方法中看到如何使这种攻击更加困难。

    另一种方法称为加盐密码。创建密码字符串时,将一个随机字符串(称为盐)连接到密码。然后对加盐密码进行哈希处理。然后将 rD、salt 和哈希存储在文件中。现在,当用户请求访问时,系统会提取盐,将其与接收到的密码连接,对结果进行哈希处理,并将其与存储在文件中的哈希值进行比较。如果有匹配,访问 被授予,否则被拒绝。加盐使字典攻击更加困难。如果原始密码是 6 位,salt 是 4 位,那么散列是对 10 位值进行的。这意味着 Eve 现在需要创建一个包含 1000 万个项目的列表,并为每个项目创建一个哈希。哈希列表有 1000 万个条目,比较需要更长的时间。如果盐是一个非常长的随机数,则盐腌非常有效。 UNIX 操作系统使用这种方法的一种变体。

    在另一种方法中,结合了两种识别技术。这种身份验证的一个很好的例子是使用带有 PIN(个人识别码)的 ATM 卡。该卡属于“拥有的东西”类别,而 PIN 属于“已知的东西”类别。 PIN实际上是增强卡安全性的密码。如果卡被盗,除非知道 PIN,否则无法使用。但是,PIN 传统上非常短,因此所有者很容易记住。这使得它容易受到猜测类型的攻击。

    来源:Behrouz A.Forouzan 的数据通信和网络

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 2011-02-05
      • 2011-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多