它是否表示密码系统错误,不允许密码中的某些字符?

信息安全 密码 密码策略
2021-08-19 01:55:18

为游戏英雄联盟创建帐户时,用户的密码必须遵守一些规则。

规则截图

我关心的是“不得包含斜杠或空格”之一。其他是健全的密码要求(嗯,除了最大长度),但不允许使用斜杠或空格似乎很奇怪。

除了以明文形式发送或保存密码时,我想不出任何其他解释,因为所述字符会破坏格式,因为在散列中这些字符会消失。仅禁止这些以防止例如 SQL 注入或其他此类事情似乎也很奇怪,特别是因为它们应该与所有数据一起正常处理。

因此,除了通过减少可用字符集来减少熵之外,这可能表明存在更深层次的问题。你怎么认为?

4个回答

禁止某些字符本身并不表示密码系统已损坏,但这是一个不好的迹象,它表明开发人员对他们的数据处理系统缺乏信心或了解不足。最可能的解释是开发人员担心某种注入攻击——SQL 注入、跨站点脚本或类似的东西。斜线和空格是这里最有可能的字符,但也许',<也是>被禁止的,或者它们可能被重新编码(但为什么不重新编码/和空格呢?)。

密码必须以明文形式发送到服务器并在那里进行散列,或者至少必须在服务器上对密码的某些编码进行散列(如果密码在客户端上进行散列,则密码散列实际上就是密码,即如果窃听者得到它就不好了)。

可能是 Web 基础设施不好(充满 SQL 注入、XSS 等),但密码哈希代码恰好调用了正确的库函数并存储了密码的加盐、慢速哈希。或者可能是密码存储在某种奇怪格式的伪数据库中,这就是禁止某些字符的原因。

这也可能是一些用户体验要求,这可能会或可能不会被解释为开发人员的意图。一些网站限制密码中的特殊字符,以防止用户选择他们无法在某些设备上轻松键入的密码。由于这是针对游戏的,可能有一个游戏内界面要求用户输入密码,但不允许使用空格或斜杠(或反斜杠,这也是被禁止的)。如果是这种情况,他们可能也应该禁止非 ASCII 字符。

查看英雄联盟的密码恢复说​​明,他们似乎没有以明文形式存储密码,而是提供了一个行业标准的密码重置链接,该链接发送到与帐户关联的电子邮件地址。安全公告提到他们的密码数据库包含“盐渍密码哈希”,因此他们似乎知道如何正确地做事。至少他们有一些基本的权利——他们链接到的页面解释了盐,但没有提到密码哈希一定很慢。尽管如此,鉴于这些线索,我并不过分担心:他们可能没有做一些非常糟糕的事情(最坏的情况,他们使用的是快速但加盐的哈希)。

您可以联系网站所有者并具体询问他们的任意要求是怎么回事。实际上,请具体询问他们使用什么密码散列算法来创建密码摘要以及他们如何计算和存储盐。

也许我有点过分了,但我的观点是,如果他们的系统是安全的,因为它是模糊的,那么它就不安全。

我不会为您用于在线银行的系统使用相同的密码,但这是一个全面的好建议(不同站点的不同密码)。

关于最大长度,公认的原始散列算法(如 SHA 算法)不关心输入长度,并且无论输入的大小如何,无论输入是三个字符还是整个大英百科全书,这些函数的输出长度都是恒定的.

如果你想要一个 100 个字符的密码,你应该可以拥有一个。

他们将您的密码限制为 16 个字符告诉我(对或错)他们可能正在存储您的明文密码,并且他们存储密码的字段长度为 16 个字符。

编辑:或者这可能表明他们正在按照旧的 LanManager 密码哈希算法做某事,使用您的密码或密码的切块部分作为对称密码(如 DES 或 AES)生成的密钥固定大小的密码哈希。这可以做对,也可以做错。他们真的在用盐吗?他们是否更喜欢快速散列算法(如果是的话,这不是一个好兆头)而不是为密码散列设计的算法,例如 scrypt/bcrypt/pbkdf2?等等。

此外,空格和斜杠与任何其他字符没有任何不同,除非它们正在执行诸如使用文件名(可能是临时文件名)的密码值或将其传递给嵌入在 SQL 或 JSON 之类的东西中的东西,在在这种情况下,他们会担心必须正确转义字符串中的这些值或破坏他们的软件。

他们应该做的是将密码作为二进制数据处理,如果他们必须将密码从一个组件传递到另一个组件(例如 Base64),则根据需要对其进行编码,并且即使在 RAM 中也不要将实际未散列的密码保留超过必要的时间,然后存储哈希。在 SHA-1 的情况下(理论上现在已被破坏),哈希是 160 位长,尽管有支持者在存储之前截断哈希(我不完全确定我在那个阵营,但它可能没问题,那就是一个不同的问题)。

安全很难做对,经常做错,经常被忽视或轻视,而且这个系统听起来很脆弱,对我来说,最重要的是。我认为你对此持怀疑态度是对的。

限制密码中允许的字符集可能有正当理由。例如,如果密码包含任何不是可打印 ASCII 字符的字符,那么在某些情况下,编码问题可能会导致正确的密码被拒绝。

此外,如果用户可能在不同的时间需要在不同的键盘布局上键入相同的密码,那么在这些键盘布局上使用不同位置的字符可能会出现问题。

攻击者可能能够找出哪些用户受到上述问题的影响,从而获得一些关于这些用户在密码中使用了哪些字符的知识。

出于上述原因限制允许的字符集并不一定会削弱密码的强度。您所要做的就是使密码稍长一些。(在极端情况下,如果您从允许所有可打印的 ASCII 变为只允许小写字母,则必须将密码长度增加 40% 才能获得相同的熵。)

限制允许的字符集也有不好的原因。例如,如果系统限制允许的字符集以防止 SQL 注入攻击,它会告诉您系统中的两个安全漏洞。首先,它没有对 SQL 查询使用正确的转义。其次,它显然不使用任何密码散列。

对于密码长度,限制可能是一个好主意,只是为了避免在某些客户端对输入字段实施任意限制的情况下出现问题。例如,如果有人认为使用带符号的字符来指示字段的长度是个好主意,那么它最多不会超过 127 个字符。我已经制作了一些系统,我在密码上强制执行最大长度为 125 个字符,以预防这种可能性(以及可能出现一对一的错误)。

如果最大长度太短,则对密码实施最大长度确实会降低安全性。您应该与您可能正在使用的对称加密原语进行比较。这意味着我们应该与块密码的块和密钥大小以及散列函数的输出进行比较。这意味着我们通常会期望我们的密码原语具有 128 到 512 位的安全性。禁止与这些安全级别匹配的密码会适得其反。根据允许的字符集,强密码中每个字符的熵可能从 4.7(仅限小写字母)到 6.57(所有可打印的 ASCII)位。通过一些数学计算,我们看到如果我们不允许至少 20 个字符,我们肯定将限制设置得太低,如果我们允许 109 个字符,我们应该非常安全。

将上限设置为 100 还是 125 不太可能对安全性产生任何实际影响,因为很可能没有用户会达到那么高。

当您提到强制执行的最大长度为 16 个字符时,这表明设计者可能出于不好的原因引入了该限制。一个不好的原因是密码被存储为纯文本,并且只分配了 16 个字符用于存储。另一个不太糟糕的原因是密码直接用作加密原语(例如 AES)的密钥。

这两个限制的组合(不允许两个特定字符和一个小的最大限制)是一个警告信号,因为它们中的每一个都可能是由于密码存储为纯文本而做出的选择。

他们决定禁止的特定字符对是空格和斜线听起来很可怕,因为我可以想象这两个特定字符不允许的原因是,他们可能希望将纯文本密码放在文件名或命令中线。希望这只是我缺乏一点想象力的问题。

我通常会告诉人们重要的网站,“如果有禁止字符,他们会存储您的密码明文。” 不一定是真的;然而,当另一端试图声称不是这样时,以下内容会被告知:“看到受限制的字符对工程师的尖叫‘我存储密码明文’比任何文档都响亮得多,如果不是真的,限制可以很容易地删除。”

由于这种普遍的压力被施加了相当长的一段时间,我们可以合理地假设剩下的大部分是真正存储明文密码的人,修复它是说“不是我们”的一种廉价方式。

结果:如果您懒得取消密码字段的限制,那么您就不值得我信任,我将把我的业务转移到其他地方。