哈希时,什么Unicode规范化(和其他处理)适用于密码?

哈希时,什么Unicode规范化(和其他处理)适用于密码?,unicode,passwords,unicode-normalization,password-storage,homoglyph,Unicode,Passwords,Unicode Normalization,Password Storage,Homoglyph,如果我接受完整的Unicode密码,我应该如何在将字符串传递给哈希函数之前规范化它 目标 如果没有规范化,如果有人在一台计算机上将密码设置为“mañana”(ma\u00F1ana),并试图在另一台计算机上使用“mañana”(ma\u006E\u0303ana)登录,哈希值将不同,登录将失败。这由用户代理或其操作系统控制 我想确保这些哈希值是相同的 我不关心同形文字,例如(希腊语、西里尔语、拉丁语) 参考文献 Unicode规范化表单: 考虑 任何规范化过程都可能导致冲突,例如,“办公

如果我接受完整的Unicode密码,我应该如何在将字符串传递给哈希函数之前规范化它

目标 如果没有规范化,如果有人在一台计算机上将密码设置为“mañana”(
ma\u00F1ana
),并试图在另一台计算机上使用“mañana”(
ma\u006E\u0303ana
)登录,哈希值将不同,登录将失败。这由用户代理或其操作系统控制

  • 我想确保这些哈希值是相同的
  • 我不关心同形文字,例如(希腊语、西里尔语、拉丁语)
参考文献 Unicode规范化表单:

考虑
  • 任何规范化过程都可能导致冲突,例如,
    “办公室”==“办公室”
  • 规范化可以更改字符串中的字节数
进一步问题
  • 如果服务器接收到无效的UTF-8(或其他格式)字节序列,会发生什么情况?拒绝,因为它不能正常化
  • 如果服务器接收到Unicode版本中未分配的字符,会发生什么情况

如果输入格式不正确,例如声称的UTF-8文本包含非法字节序列,则未定义规范化。非法字节在不同的环境中可能会有不同的解释:拒绝、替换或省略

建议#1:如果可能,拒绝不符合预期编码的输入。(但是,这可能超出应用程序的控制。)

Unicode附录15保证了输入仅包含指定字符时的规范化稳定性:

11.1规范化形式的稳定性

对于所有版本,即使在Unicode 4.1之前,也遵循以下策略:

规范化字符串保证是稳定的;也就是说,一旦规范化,字符串将根据Unicode的所有未来版本进行规范化

更准确地说,如果字符串已经根据特定版本的Unicode进行了规范化,并且只包含在该版本中分配的字符,那么它将符合未来任何版本的Unicode的规范化条件

建议#2:无论使用哪种规范化形式,都必须使用,即拒绝任何包含未分配字符的密码输入,因为在服务器升级下,它们的规范化不保证稳定

兼容性规范化表单似乎可以更好地处理日语,将多个分解折叠到同一个输出中,而规范化表单则没有

规范警告:

规范化表单KC和KD不能盲目地应用于任意文本。由于它们会删除许多格式差异,因此会阻止与许多传统字符集之间的往返转换,并且除非被格式标记取代,否则它们可能会删除对文本语义很重要的差异

然而,这里并不关心语义和往返


建议#3:在散列之前应用NFKC或NFKD。

您主要关心的是用户在不同设备上使用不同的输入方法吗?您的示例包括连接器,但是零宽度连接器和组合器呢?类似但语义不同的代码点,如I(拉丁字母)vsⅠ(罗马数字)vsI (CJK全宽)?我不关心同形符——他们不太可能使用只共享一些(接近)同形符的输入法键入整个密码——但我必须考虑加入者。也许准备Unicode进行密码散列需要一种更彻底的方法。回答得好。如果能参考RFC4013()及其替代品saslprepbis(),那就更好了。哦,很好的参考资料!是否要编辑答案以包含这些内容?恐怕我所有的Unicode规范化知识现在都没有了-(这些引用已被取代。RFC 7613()淘汰了RFC 4013,而PRECIS框架()是saslprepbis过程的最终结果。NFKD是一种方法,如果使用NFKC并将新的预合成字符添加到unicode中,则结果将不同。