在这种情况下,罪魁祸首是一家特定的(特别是大的)银行,它的密码中不允许使用特殊字符(任何类型的):Just [aZ 1-9]。他们这样做有什么正当理由吗?像这样限制密码强度似乎适得其反,特别是对于保护此类有价值信息的系统。
我唯一能想到的就是阻止 SQL 注入的弱尝试,但这会假设密码没有被散列(我当然希望这不是真的)。
在这种情况下,罪魁祸首是一家特定的(特别是大的)银行,它的密码中不允许使用特殊字符(任何类型的):Just [aZ 1-9]。他们这样做有什么正当理由吗?像这样限制密码强度似乎适得其反,特别是对于保护此类有价值信息的系统。
我唯一能想到的就是阻止 SQL 注入的弱尝试,但这会假设密码没有被散列(我当然希望这不是真的)。
我在这里没有看到的一种解释是,许多金融机构与旧系统紧密集成,并且受到这些系统的限制。
具有讽刺意味的是,我已经看到为与旧系统兼容而构建的系统,但现在旧系统已经消失,并且必须存在与新系统兼容的策略,而新系统是为与旧系统兼容而构建的。
(这里的教训是,如果您必须与旧系统兼容,请允许将来消除这些限制)。
支持费用呢?假设我们允许任何人创建包含€
字符的密码。万岁,我们可以在密码中使用特殊字符。但是等等——如果我们想通过手机访问我们的银行,我们究竟如何输入密码呢?€
用我们的键盘打字比用手机打字更容易。
假期呢?我们在英国,只能使用英国键盘。而不是€
我们可以轻松地键入£
. “容易”这个词在这里非常重要。对于一些普通用户来说,在“新”键盘上键入该字符可能是个问题。他们将如何尝试解决它?他们可能会打电话给银行支持,要求他们更改密码或询问为什么该€
字符从键盘上消失了。
这可以(微弱地)被证明是一种深度防御措施——如果存在注入或其他数据解释错误,限制密码字符集和长度可能能够防止它被利用。它还稍微简化了实现,因为如果它们只处理 7 位 ASCII 字符,则 Unicode 和多字节字符串处理是无关紧要的,而且更简单的实现通常不太可能包含错误。
然而,评估这种降低的风险与由于较低的密码质量而增加的风险并不简单——我预计随着系统用户数量的增加,可能被泄露的密码数量也会增加,因此投资于解除此类风险限制更值得。话虽如此,即使该字段完全不受限制,大多数用户的密码也会很糟糕。
我的猜测是所有用户输入的字段都存在该策略,并且为简单起见,相同的用户输入策略(无特殊字符)应用于包括密码的字段。或者在某些时候,一些银行没有对密码进行哈希处理,并且通过他们的密码字段进行了 SQLi 攻击,并且决定密码不能包含特殊字符(并且一旦引入哈希处理就忘记了该策略的原因)。
不允许在其他用户输入的字段中使用未散列的特殊字符肯定有安全优势,这些字符可用于 SQLi 或 XSS 等各种攻击(在银行管理员查看帐户时)。但是,这些威胁通常通过始终在 SQL 中使用绑定参数并始终在显示/保存到 db 之前清理用户输入来解决。
我的另一个猜测是,他们希望拥有可能与其他地方不同的自定义规则,因此您不能轻易地重用标准强密码(可能会丢失),并且必须为他们的网站想出一些独特的东西。
编辑:进一步考虑,根据语言,我可以想到至少三个特殊的 ASCII 字符,这些字符应该被普遍禁止/剥离,因为它们只会诱惑命运。具体来说:\0
(null - ascii 0),因为它习惯上用于指示 C 风格语言中的字符串结尾(可能用户在字符串结尾之后更改内存)。还有回车和换行\r
(ascii 13)和\n
(ascii 10),因为这些通常取决于系统,无论换行符是\r\n
还是\n
,这带来了不可避免的我只能从 Windows 而不是我的 mac/linux 机器登录。事实上,只允许可打印的 ascii (32-126) 而禁止不可打印的 ASCII 0-31 和 127 似乎是很合理的。
但是,如果使用特殊字符,您的意思是 unicode 而不是 ASCII 字符(就像,./<>?;':"[]{}\|!@#$%^&*(-=_+
从多个操作系统/键盘/浏览器实现的简单性而言,不允许特殊字符似乎是合理的。想象一下您的密码中有一个小写的 pi。那是希腊语 pi( π) 是代码点 0x3c0 或科普特小写 pi (ⲡ) 是代码点 0x2ca1 - 只有一个可以工作,这种类型的具有不同代码点的相似字符的问题将存在于 unicode。您对位进行操作的哈希将无法使两个 π 相等,因此如果您尝试在不同的地方登录,您可能会输入不同的字符。
同样,尽管这个问题是程序员可以在很大程度上控制并尝试纠正的问题,但允许 unicode 字符会产生编码问题。这对于您的基本 ascii 字符而言,所有内容都以一个字节数表示。但是,对于如何编码 unicode,有很多不同的方案。是 UTF-7、UTF-8、UTF-16、UTF-32、Latin-1 (iso-8859-1)、Latin-N 编码吗,以及(对于某些编码)字节顺序是什么(小端或大端) ? pi (0x3c0) 的 unicode 代码点将2b 41 38 41 2d
在 UTF-7、CF 80
UTF-8、FF FE c0 03
UTF-16 和FF FE 00 00 c0 03 00 00
UTF-32 中表示为字节。您将无法用 Latin-1 表示 pi(它只有 95 个额外的可打印字符),但是如果您有A1
在您的密码中并且使用不同的编码,您可能必须使用以下任何字符¡ĄĦЁ‘ก”Ḃ
(在某些拉丁语 N 中可能为 A1)来表示它。
是的,网页可能定义了字符集,但用户可以在浏览器中覆盖页面上的字符集,或者以不同的编码从其他地方复制和粘贴数据。归根结底,禁止这些字符可能更简单。