为何使用Django make_password生成相同字符串哈希每次结果不同?
为什么Django的make_password对同一字符串每次生成的哈希都不一样?
嘿,这个问题我当初刚接触Django认证系统的时候也困惑过!其实这完全是正常设计,而且是Django为了提升密码安全性特意做的优化~
核心原因:加盐哈希(Salted Hashing)
我们平时说的“同一输入得到同一哈希”,指的是无盐的普通哈希函数(比如MD5、SHA-1),但这种方式安全性极低——黑客可以用彩虹表(预计算好的密码-哈希映射表)轻松破解。
而Django的make_password默认使用的是加盐哈希算法(默认是pbkdf2_sha256),每次调用时会自动生成一个随机的唯一盐值,然后把这个盐值和你的原始密码混合后再进行哈希计算。因为盐值每次都不一样,所以最终生成的哈希结果自然不同。
哈希字符串的结构解析
你生成的哈希值格式大概是这样的:
pbkdf2_sha256$20000$Tr6NV5MewXYl$X+sezT6WRqB...
我们可以拆分成4个部分:
pbkdf2_sha256:使用的哈希算法类型20000:哈希计算的迭代次数(次数越高,破解难度越大)Tr6NV5MewXYl:本次生成的随机盐值- 最后一段:盐值+原始密码经过哈希计算后的最终结果
那怎么验证密码呢?
不用担心验证问题,Django的check_password函数会自动处理:它会从存储的哈希字符串里提取出盐值、算法和迭代次数,然后用同样的规则对用户输入的密码进行哈希计算,最后对比两次的哈希结果是否一致。所以哪怕每次生成的哈希不同,也能准确验证密码是否正确。
题外话:能不能强制生成相同的哈希?
理论上可以——你可以手动指定盐值,比如:
from django.contrib.auth.hashers import make_password password = "helloworld" h1 = make_password(password, salt="my_fixed_salt") h2 = make_password(password, salt="my_fixed_salt") # 此时h1和h2会完全相同
但非常不推荐这么做,固定盐值会让密码失去加盐哈希的安全防护,大大提升被破解的风险。
内容的提问来源于stack exchange,提问作者coda
相关产品推荐
相关产品推荐

