tre*_*ell 16 passwords unicode password-storage unicode-normalization homoglyph
如果我接受完整的Unicode密码,我应该如何在将字符串传递给哈希函数之前对其进行规范化?
如果没有规范化,如果有人ma\u00F1ana
在一台计算机上将其密码设置为"mañana"()并尝试使用ma\u006E\u0303ana
另一台计算机上的"mañana"()登录,则哈希将不同,登录将失败.这受用户代理或其操作系统的控制.
Unicode规范化形式:http://unicode.org/reports/tr15/#Norm_Forms
"o?ce" == "office"
.tre*_*ell 12
如果输入格式错误,例如涉嫌包含非法字节序列的UTF-8文本,则规范化是不确定的.在不同的环境中,非法字节可能会有不同的解释:拒绝,替换或遗漏.
建议#1:如果可能,拒绝不符合预期编码的输入.(但这可能超出了应用程序的控制范围.)
当输入仅包含指定的字符时,Unicode附件15可确保标准化稳定性:
11.1规范化形式的稳定性
对于所有版本,甚至在Unicode 4.1之前,遵循以下策略:
规范化的字符串保证稳定; 也就是说,一旦规范化,就会根据Unicode的所有未来版本对字符串进行规范化.
更准确地说,如果字符串已根据特定版本的Unicode进行规范化并且仅包含在该版本中分配的字符,则它将符合根据Unicode的任何未来版本进行规范化.
建议#2:无论使用哪种规范化形式,都必须使用稳定字符串的规范化过程,即拒绝任何包含未分配字符的密码输入,因为在服务器升级时,它们的规范化不能保证稳定.
兼容性规范化形式似乎更好地处理日语,将几个分解折叠到规范形式不相同的输出中.
规范警告:
规范化表格KC和KD不得盲目地应用于任意文本.因为它们会消除许多格式区别,所以它们会阻止往返许多遗留字符集的往返转换,除非通过格式化标记取代,否则它们可能会删除对文本语义重要的区别.
但是,这里不关心语义和往返.
建议#3:在散列之前应用NFKC或NFKD.