This repository was archived by the owner on Jun 6, 2021. It is now read-only.
Replies: 1 comment
-
|
我想出了一种向后兼容的解决方案(大概),现在初次登录的时候用的是以前的算法,验证成功后会把用户密码迁移到新的算法,之后都是用新的算法验证了。参见06ec536。 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
以前的实现:
其中存在两个问题:
scrypt的第二个参数类型为string | Buffer。当其为string时,node会把它理解为UTF8编码的字符串,也就是说base64编码的salt会被以UTF8解码,导致实际上salt的长度大于16。这是错误(至少是非意料)的实现,但是因为哈希与验证时都是将错就错,所以它工作。例子:scrypt以Buffer格式返回哈希,Buffer.toString有一个可选参数,即编码,默认是UTF8。这就带来了另一个问题:unicode在编码无效字符时,会将其替换为U+FFFD,而scrypt的结果可能(极大概率)会包含无效的unicode字符,导致它们全部被替换为了U+FFFD。这是大错特错的实现,而且正好也是因为哈希与验证时都是将错就错,所以它工作。例子(以我自己的密码为例):长度为62(尽管不是真正的长度)的哈希里,有33个都是0xFFFD,极大增加了碰撞的可能性(尽管我们的体量太小,没人会对我们做这种事)。
附上正确的实现:
采取正确的实现后,所有用户都需要重新设置密码,但是它毕竟是正确的。
所以投票,滋磁采取正确的实现按👍,反对按👎。
Beta Was this translation helpful? Give feedback.
All reactions