我正在处理一个旧数据库,其中包含$2y
哈希值。我已经深入了解了这一点,也发现了和$2y
之间的区别。
我看着节点模块bcrypt
似乎生成并仅比较$2a
散列。
- https://github.com/ncb000gt/node.bcrypt.js/issues/175
- https://github.com/ncb000gt/node.bcrypt.js/issues/349
- https://github.com/ncb000gt/node.bcrypt.js/issues/213
我发现了一个网站,产生$2y
哈希这样我就可以bcrypt
测试。
这里有一个$2y
哈希字符串helloworld
的一个例子。
helloworld:$2y$10$tRM7x9gGKhcAmpeqKEdhj.qRWCr4qoV1FU9se0Crx2hkMVNL2ktEW
看来模块没有验证$2y
哈希的方式。
这是我的测试。
var Promise = require('bluebird')
var bcrypt = require('bcrypt')
var string = 'helloworld'
Promise.promisifyAll(bcrypt)
// bcrypt.genSalt(10, function(err, salt) {
// bcrypt.hash(string, salt, function(err, hash) {
// console.log(hash)
// })
// })
var hashesGeneratedUsingBcryptModule = [
'$2a$10$6ppmIdlNEPwxWJskPaQ7l.d2fblh.GO6JomzrcpiD/hxGPOXA3Bsq',
'$2a$10$YmpoYCDHzdAPMbd9B8l48.hkSnylnAPbOym367FKIEPa0ixY.o4b.',
'$2a$10$Xfy3OPurrZEmbmmO0x1wGuFMdRTlmOgEMS0geg4wTj1vKcvXXjk06',
'$2a$10$mYgwmdPZjiEncp7Yh5UB1uyPkoyavxrYcOIzzY4mzSniGpI9RbhL.',
'$2a$10$dkBVTe2A2DAn24PUq1GZYe7AqL8WQqwOi8ZWBJAauOg60sk44DkOC'
]
var hashesGeneratedUsingAspirineDotOrg = [
'$2y$10$MKgpAXLJkwx5tpijWX99Qek2gf/irwvp5iSfxuFoDswIjMIbj2.Ma',
'$2y$10$tRM7x9gGKhcAmpeqKEdhj.qRWCr4qoV1FU9se0Crx2hkMVNL2ktEW'
]
var hashesGeneratedUsingAspirineDotOrgSwippedYForA = [
'$2a$10$MKgpAXLJkwx5tpijWX99Qek2gf/irwvp5iSfxuFoDswIjMIbj2.Ma',
'$2a$10$tRM7x9gGKhcAmpeqKEdhj.qRWCr4qoV1FU9se0Crx2hkMVNL2ktEW'
]
hashesGeneratedUsingBcryptModule = hashesGeneratedUsingBcryptModule.map(hash => bcrypt.compareAsync(string, hash))
hashesGeneratedUsingAspirineDotOrg = hashesGeneratedUsingAspirineDotOrg.map(hash => bcrypt.compareAsync(string, hash))
hashesGeneratedUsingAspirineDotOrgSwippedYForA = hashesGeneratedUsingAspirineDotOrgSwippedYForA.map(hash => bcrypt.compareAsync(string, hash))
Promise.all(hashesGeneratedUsingBcryptModule)
.tap(() => console.log('hashesGeneratedUsingBcryptModule'))
.then(console.log)
Promise.all(hashesGeneratedUsingAspirineDotOrg)
.tap(() => console.log('hashesGeneratedUsingAspirineDotOrg'))
.then(console.log)
Promise.all(hashesGeneratedUsingAspirineDotOrgSwippedYForA)
.tap(() => console.log('hashesGeneratedUsingAspirineDotOrgSwippedYForA'))
.then(console.log)
下面是结果:
// hashesGeneratedUsingAspirineDotOrg
// [ false, false ]
// hashesGeneratedUsingBcryptModule
// [ true, true, true, true, true ]
// hashesGeneratedUsingAspirineDotOrgSwippedYForA
// [ false, false ]
我难倒我如何在节点比较$2y
哈希值。
有another Stack Overflow question/answer,说你可以只改变$2y
到$2a
,但还是失败了我。
更新!
我错误地使用了the generator,因为它是一个.htpasswd
密码生成器,您必须以此格式输入用户名和密码。
reggi helloworld
和输出对应的位置:
reggi:$2y$10$iuC7GYH/h1Gl1aDmcpLFpeJXN9OZXZUYnaqD2NnGLQiVGQYBDtbtO
之前,我作为把刚刚
helloword
这我假设散列一个空字符串。
由于这些变化将y
更改为a
在bcrypt
工程。而twin-bcrypt
只是工作。
我依稀记得有更好的运气工作的另一种方式 - 以'$ 2A $''通过javascript中bcrypt'产生的哈希值,以取代''2a' 2Y ',然后使用其他语言的'2y'库(本地php和来自.net的'BCrypt')都可以处理它,这让我觉得很奇怪)。我可以挖掘我的测试代码,如果这对你有帮助。 – dvlsg
@dvlsg明白了。这就说得通了。所以我需要比较节点中的$ 2y哈希值,而不是php中的$ 2a哈希值,我猜这是通过将'a'替换为'y'来实现的。 – ThomasReggi
是的,我实际上是在数据库中存储哈希值为'$ 2y',将它们原样用于PHP和.NET,但是当我在节点中使用它们时,我有一个额外的转换步骤,将'y'交换回比较之前的'a'。它感觉不对,但它看起来像'2a'和'2y'对于salt/hash的其余部分使用相同的结构。 – dvlsg