相同密码下password_hash()生成不同哈希及password_verify()工作原理问询
密码哈希相关函数底层机制解答
问题1:相同密码调用password_hash()是否会生成不同哈希?实现原理是什么?
- 结论是会,在默认配置下,即便两个用户的明文密码完全一致,调用
password_hash()生成的哈希结果也完全不同。 - 实现原理:
password_hash()默认采用bcrypt、Argon2i/Argon2id等抗碰撞、支持随机加盐的密码哈希算法。函数每次执行时都会自动生成全局唯一的随机盐值,将盐值与明文密码拼接后再进行哈希运算,最终输出的完整哈希串会直接包含四个部分:算法标识、运算成本参数、本次使用的随机盐值、盐+密码运算得到的哈希结果。
以bcrypt算法生成的哈希为例,结构为$2y$[成本参数]$[22位随机盐][31位哈希结果],相同密码两次调用生成的哈希串,随机盐部分完全不同,自然最终整体哈希结果也不同。
问题2:密码相同时password_verify()的校验逻辑是怎样的?
password_verify()接收两个入参:用户输入的明文密码、数据库存储的预先生成的哈希串,底层校验逻辑如下:
- 首先从预生成的哈希串中,解析出对应的算法类型、运算成本参数、生成该哈希时使用的随机盐值
- 用解析得到的算法、参数、盐值,对用户输入的明文密码重新执行一次哈希运算,生成临时哈希串
- 采用时序安全的字符串比较方法,比对临时哈希串和预生成的哈希串是否完全一致,一致则返回校验通过,否则返回校验失败
因为相同明文密码、相同盐值、相同算法参数下,哈希运算的结果是唯一的,所以哪怕password_hash()每次生成的哈希串不同,只要明文密码正确就能通过校验。
内容的提问来源于stack exchange,提问作者Mizugorou
相关产品推荐
相关产品推荐

