密码该怎么存?默认的哈希够不够强?库里还有旧的弱哈希怎么办?这篇量出每种方法的真实耗时,并实现一遍「登录时顺便升级」的流程。
默认哈希: scrypt:32768:8:1$1BqMQRrogW6XwUBP$627fa23b94221e17cbf4a374b1… (长度 162) 同一个密码再来一次: scrypt:32768:8:1$DaH1695lpnGSOVxb$9d6a5c809885b3eccdc7d682b9… | 两次相同吗: False 结构:方法$盐$摘要 → scrypt:32768:8:1 | 盐 16 个字符 | 摘要 128 个十六进制字符 check_password_hash 正确/错误: True False
上一篇:Rate Limiting;下一篇:登录失败锁定。
pbkdf2:sha256:1000(旧的、太弱) 0.131 ms pbkdf2:sha256:600000 65.161 ms scrypt(Werkzeug 默认 32768:8:1) 66.000 ms scrypt:131072:8:1 266.391 ms argon2id(argon2-cffi 默认) 30.137 ms sha256 一次(错误示范,不要用) 0.001 ms 差距:scrypt 默认比单次 sha256 慢 93085 倍
升级前: {'ann': 'pbkdf2:sha256:1000', 'bob': 'scrypt:32768:8:1'}
ann 用错误的密码登录: fail | 哈希仍是 pbkdf2:sha256:1000
ann 正确登录: ok(并已升级哈希)
ann 再登录一次: ok | bob 登录: ok
升级后: {'ann': 'scrypt:32768:8:1', 'bob': 'scrypt:32768:8:1'}
(没有登录过的用户仍是旧哈希——升级只发生在用户登录、明文密码在手的时候)旧参数哈希头: scrypt:16384:8:1 | 新参数哈希头: scrypt:131072:8:1 两者都能用同一个 check_password_hash 验证: True True
10 万个字符的密码哈希耗时 67.4 ms,哈希长度 162 空字符串密码也能哈希并验证: True (这次测量里耗时没有随密码长度明显增加,和默认的 65 ms 差不多;是否仍要在应用层限制密码长度,这里没有验证)
$argon2id$v=19$m=65536,t=3,p=4$ww695w9iuw7iKH0hmnKluQ$/fE07J… 验证: True | check_needs_rehash(默认参数): False 用更弱参数生成的哈希,按默认参数 check_needs_rehash → True (argon2-cffi 自带「是否需要升级」的判断)
argon2-cffi 是我额外装进环境的,Flask 与 Werkzeug 本身不带它。