bcrypt的密码校验是如何工作的?为何无需单独存储salt?
bcrypt 设计时就已经解决了盐的存储问题,你不需要单独保存生成的salt,核心逻辑如下:
- hash返回值内置全部校验所需参数
bcrypt.hashpw生成的完整哈希串并不是只包含密码的哈希结果,而是把算法版本、迭代成本、salt三个信息都拼接在了哈希值的前面,标准结构类似:
$2b$12$Z3Ht4Kj7Lp9Xs2VbN8MqR$Uc7yF3dS9aW2eD5fR7tG8hYj9K0lM3nP5o7I9u
各段用$分隔的含义:
- 第一段
2b:bcrypt算法的版本标识 - 第二段
12:哈希计算的迭代成本因子(即会执行2^12次哈希运算) - 第三段前22位:你调用
bcrypt.gensalt()生成的随机盐 - 剩余部分:明文密码结合前面的参数计算得到的最终哈希值
- checkpw的执行逻辑
你调用bcrypt.checkpw(明文密码, 已存储的哈希串)时,函数会自动从传入的哈希串里解析出salt、算法版本、迭代成本这三个参数,再用这些参数对输入的明文密码做哈希计算,最后把计算得到的结果和传入哈希串里的最终哈希部分做对比,一致就返回匹配成功。
你给出的示例里hashed变量已经包含了salt等全部所需信息,所以你只需要把这个hashed值存到数据库里即可,不需要额外单独存储salt,校验时直接传这个值就可以正常工作。
内容的提问来源于stack exchange,提问作者Oleg Ivanytskyi
相关产品推荐
相关产品推荐

