验证密码的严格程度


How strict to verify passwords?

对于多用户站点,我应该多严格地验证用户的密码?

我搜索了一下,只找到了有关如何验证用户密码的问题。但是我知道如何为存储在数据库中的密码创建加盐哈希(PHP的password_hash()),并且我知道如何验证这些密码(PHP的password_verify())。

我问我应该对我的网站上的用户密码进行哪些类型的限制。由于密码永远不会显示在网页上,我应该像用户名一样对它们进行严格的限制吗?

我知道显示用户名,并且

容易受到XSS攻击(我已经阻止了用户名),但是密码是不同的,并且不能以这种方式被黑客入侵(我认为这就是它的工作原理;如果我错了,请纠正我)。

我知道密码通常是个人的,而且非常独特。我不知道我是否应该限制可以使密码更安全的特殊字符,包括类似于XSS攻击中的特殊字符。

我问是否应该允许任何密码(在某些字符限制内);如果没有,那么推荐的(安全)方法是什么?

您应该允许 ASCII 字符集中的任何字符(尽管如果您想稍微复杂一点,例如在使用密码强度计时,您可以允许 unicode)。如果使用 bcrypt,则应将最大长度设置为 72 个 ASCII 字符,因为 PHP 实现将哈希限制为仅以下字符:

对 algo 参数使用 PASSWORD_BCRYPT将导致密码参数被截断为最大长度为 72 个字符

这很好,因为某些实现对长度(55 个字符)施加了更大的限制。

使用 Unicode,这也更复杂,因为某些字符最多可能需要 4 个字节。我的建议:坚持使用ASCII,密码可以足够安全(>= 64位熵),因为它使事情变得简单,如果您的用户使用密码管理器(他们应该这样做),则大多数密码管理器仅支持ASCII字符集。

XSS 仅在数据输出到页面时才是一个问题。理想情况下,您的系统应实施一项策略,即密码仅输入,从不输出(即使在<input type="password" />字段中)。这将长期增强密码的安全性。

首先,密码强度。
这对于防止密码猜测或暴力攻击非常重要。密码越强 - 当然越好。例如,您可以将其限制为至少 10 个字符,并要求其中包含数字和大写字符。这已经相当强大了,但你也可以要求使用符号,如!$@#等。该密码将非常安全。

至于安全地存储密码 - 这是一个不同的主题 - 您永远不应该以开放形式存储或显示密码。始终使用它们进行哈希处理,例如:

$password = password_hash($password, PASSWORD_DEFAULT);

并将生成的字符串存储在数据库中。
这在今天被认为是最安全的。

要检查输入的密码是否正确,您需要做的就是使用函数 password_verify() ,将输入的密码与存储的哈希密码进行比较。

$success = password_verify($entered_password, $hash_stored_in_mysql);

$success将变得truefalse,这就是您需要知道的密码是否匹配的全部内容。

很高兴今天有这个password_hashpassword_verify,在添加这个有用的功能之前,人们使用了很多愚蠢和错误的方式来散列或加密密码!