可以使用 NFC/NFD 规范化 unicode 密码吗?

信息安全 密码 统一码
2021-08-11 13:54:23

我目前正在为 Web 服务设计登录。我将使用 PBKDF2 实现对密码进行哈希处理。

但是,我打算允许密码使用 unicode,因为我将拥有国际用户,他们可能想要使用例如西里尔字符。为了避免 unicode 歧义的任何问题,我想在将密码编码为 utf8 并将其传递给哈希之前使用 NFC unicode 规范化。

现在的问题是:这是安全的,还是会在密码验证中引入任何不必要的歧义?很明显,"a\u0308"(a + 组合分叉)和"ä"应该是相同的,但是 NFC 是否折叠了用户可能依赖的更多差异?

编辑

我发现有一个名为SASLprep (RFC 4013)的 stringprep ( RFC 3454 ) 配置文件,它在某些协议中似乎用于密码和用户名。它指定使用 KD 归一化,我认为这是一个坏主意。它将折叠差异,例如,这至少是西方世界键盘上常见的两个字符,可用于丰富密码熵。不幸的是,没有给出任何理由。²2

1个回答

如果您将 2 和 ² 视为同一个字符,则实际上是从字符集中删除了一个字符。如果它增加了可用性,那并不是那么糟糕,特别是如果它鼓励更长的密码。

假设您使用 8 个字符的密码,从一组 2000 个字符中随机抽取一个。这给出了 log₂(2000⁸) ≈ 88 位的熵。如果您有一个 9 个字符的密码,从 1000 个字符(一半!)中提取,那就是 log₂(1000⁹) ≈ 90 位熵。实际上:

+-----+---------------------------+
|     |    character set size     |
| len |  500 | 1000 | 2000 | 4000 |
|-----+------+------+------+------|
| 6   |  54  |  60  |  66  |  72  |
| 7   |  63  |  70  |  77  |  84  |
| 8   |  72  |  80  |  88  |  96  |
| 9   |  81  |  90  |  99  |  108 |
| 10  |  90  |  100 |  110 |  120 |
| 11  |  99  |  110 |  121 |  132 |
+---------------------------------+

如您所见,在密码长度和 Unicode 字符集大小的正常范围内,字符集的确切大小并不那么重要。