我正在处理一个带有$2y哈希值的旧数据库.我已经挖了一下,在
the stack overflow上偶然发现了$2a和$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
我找到了一个产生2美元哈希的网站,所以我可以用bcrypt来测试它们.
> http://aspirine.org/htpasswd_en.html
这是一个$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,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 ] // 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中工作.而双胞胎正好适用.
解决方法
>使用bcrypt时,将y更改为a.
>当使用twin-bcrypt时,哈希就可以了.
>当使用twin-bcrypt时,哈希就可以了.
使用http://aspirine.org/htpasswd_en.html时,请确保提供用户名和密码.
reggi helloworld
然后:
reggi:$2y$10$Am0Nf/B6.S/Wkpr6IVdIZeuHWNa/fqoLyTNmlyrSg22AjRf2vS.T.
这是一个包含bcrypt和twin-bcrypt的工作示例.
var twinBcrypt = require('twin-bcrypt') var bcrypt = require('bcrypt') var string = 'helloworld' var bcryptAttempt = bcrypt.compareSync(string,"$2y$10$Am0Nf/B6.S/Wkpr6IVdIZeuHWNa/fqoLyTNmlyrSg22AjRf2vS.T.".replace(/^\$2y/,"$2a")) console.log(bcryptAttempt) var twinBcryptAttempt = twinBcrypt.compareSync(string,"$2y$10$Am0Nf/B6.S/Wkpr6IVdIZeuHWNa/fqoLyTNmlyrSg22AjRf2vS.T.") console.log(twinBcryptAttempt)
输出:
true true