首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个JWT匹配散列JWT

多个JWT匹配散列JWT
EN

Stack Overflow用户
提问于 2021-12-15 22:32:04
回答 1查看 174关注 0票数 1

在将用户的refresh_token存储在数据库中之前,我使用bcryptjs对其进行散列。

当将散列字符串与JWT进行比较时,下面的计算结果似乎总是为true,我在https://bcrypt-generator.com/上也得到了相同的行为

例如,散列$2a$10$z4rwnyg.cVtP2SHt3lYj7.aGeAzonmmzbxqCzi2UW3SQj6famGaqW与以下两个JWT匹配

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTZlODdkNi1jMmVkLTRmN2ItOTU2Zi00NDFhMWU1NjA2MmQiLCJpYXQiOjE2Mzk1OTg2MDIsImV4cCI6MTY0MjE5MDYwMn0.aJlzFHhBMGO4J7vlOudqOrOFnL1P-yEGrREgdaCXlxU

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTZlODdkNi1jMmVkLTRmN2ItOTU2Zi00NDFhMWU1NjA2MmQiLCJpYXQiOjE2Mzk2MDY4ODgsImV4cCI6MTY0MjE5ODg4OH0.vo4HKLXuQbT0Yb0j21M4xl-rakxyE5wINjuGdkPuSJY

您也可以在网站上验证它们是否都会导致“匹配”。

  1. 转到https://bcrypt-generator.com/并打开浏览器控制台。
  2. 将这些行输入控制台:var "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTZlODdkNi1jMmVkLTRmN2ItOTU2Zi00NDFhMWU1NjA2MmQiLCJpYXQiOjE2Mzk1OTg2MDIsImV4cCI6MTY0MjE5MDYwMn0.aJlzFHhBMGO4J7vlOudqOrOFnL1P-yEGrREgdaCXlxU“= "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTZlODdkNi1jMmVkLTRmN2ItOTU2Zi00NDFhMWU1NjA2MmQiLCJpYXQiOjE2Mzk2MDY4ODgsImV4cCI6MTY0MjE5ODg4OH0.vo4HKLXuQbT0Yb0j21M4xl-rakxyE5wINjuGdkPuSJY”< undefined > var jwt2 =“eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NTZlODdkNi1jMmVkLTRmN2ItOTU2Zi00NDFhMWU1NjA2MmQiLCJpYXQiOjE2Mzk2MDY4ODgsImV4cCI6MTY0MjE5ODg4OH0.vo4HKLXuQbT0Yb0j21M4xl-rakxyE5wINjuGdkPuSJY”< undefined > var h= "$2a$10$z4rwnyg.cVtP2SHt3lYj7.aGeAzonmmzbxqCzi2UW3SQj6famGaqW“<未定义
  3. 然后将这些行输入控制台,观察它们如何返回truebcrypt.compareSync(jwt1,h) < true > bcrypt.compareSync(jwt2,h) < true

这是我自己的JS代码,它还复制哈希匹配:

代码语言:javascript
复制
// Login Logic

const refresh_token: string = jwt.sign({ userId }, authSecrets.refresh_secret, { expiresIn: '30d' });

const hash_refresh = bcrypt.hashSync(refresh_token);

await UserModel.update({
    id: user.id,
    refresh_token: hash_refresh,
});
代码语言:javascript
复制
// Refresh logic
// 'value' is the payload after using joi to validate it 

const claims: any = jwt.verify(value.refresh_token, authSecrets.refresh_secret);

user = await UserModel.get(claims.userId);

if (!bcrypt.compareSync(value.refresh_token, user.refresh_token)) {
    // This never happens with any JWT!
    return response(401, 'Refresh Token is incorrect');
}

为什么会发生这种情况?字符串显然是不同的(虽然不是很多)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-15 23:03:37

哈希冲突是因为bcrypt 只散列输入的前72字节。 (在大多数实现中)。

这在bcryptjsbcrypt npm包的自述文件中都有记录:

bcryptjs

最大输入长度为72个字节(注意,UTF8编码的字符最多需要4个字节),生成的哈希长度为60个字符。

bcrypt

根据bcrypt实现,只使用字符串的前72个字节。当匹配密码时,任何额外的字节都会被忽略。请注意,这不是前72个字符。字符串可能包含少于72个字符,而占用超过72个字节(例如,包含emojis的UTF-8编码字符串)。

(这是一个客观上糟糕的设计,考虑到这是为了用户安全.如果输入超过72字节,bcryptjs库实际上应该总是抛出异常。

我注意到bcrypt是为人提供的(即非随机)密码而设计的,而不是作为一个通用的消息摘要算法。如果您不需要向随机生成的密码(比如您的refresh_token值)添加盐,那么您可能应该为此使用类似SHA-2家族算法(例如SHA-256,而不是SHA-1)的方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70371126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档