如何在哈希存储密码的前提下检测用户改密时使用相似字符串?
密码相似性检测的安全实现方案
针对你提到的“不能将密码修改为相似字符串”的需求,同时要保证服务器被攻破时用户密码安全,有以下几种无需存储明文密码的可行方案:
1. 模糊哈希(SimHash)存储方案
SimHash的核心特性是相似文本生成的哈希值也相似,刚好能解决普通哈希对微小字符变化极度敏感的问题。实现步骤:
- 用户设置/修改密码时,对明文密码计算SimHash值,将这个模糊哈希与密码的强哈希(比如bcrypt)分开存储。
- 用户修改密码时,先验证旧密码的正确性,再计算新密码的SimHash,与存储的旧SimHash计算汉明距离(比如阈值设为3),如果距离过小则判定为相似密码,禁止修改。
- 安全性:SimHash是不可逆的,即使服务器被攻破,攻击者无法通过SimHash还原出原密码,只会得到一个用于相似性比对的模糊标识。
2. 密码特征哈希存储方案
提取密码的非敏感核心特征,对特征进行哈希后存储,避免直接关联明文密码:
- 提取的特征可以包括:密码主体序列(比如去掉末尾的符号/大小写变化后的核心部分)、字符类型组合(数字/小写字母/大写字母/符号的数量占比)、密码长度、关键子串(比如连续数字/字母的长度)。
- 存储这些特征的哈希值(比如用SHA-256),用户修改密码时,提取新密码的相同特征并哈希,与旧特征哈希对比匹配度,匹配度过高则禁止修改。
- 安全性:特征本身不包含完整密码信息,哈希后的特征无法还原出原密码,即使泄露也不会威胁用户密码安全。
3. 客户端+服务器双重检测方案
- 客户端层面:在用户输入新密码时,直接用编辑距离算法(比如Levenshtein距离)对比新密码与旧密码的明文(旧密码由用户输入),如果相似度超过阈值(比如编辑距离≤2),前端直接提示用户修改。
- 服务器层面:为了防止客户端被篡改绕过,服务器可以结合前面的SimHash或特征哈希方案,对新密码做二次相似性验证。
- 安全性:服务器始终只存储密码的强哈希值,客户端的检测不会泄露任何密码信息到服务器,双重保障既实现需求又保证安全。
内容的提问来源于stack exchange,提问作者Terry Windwalker
相关产品推荐
相关产品推荐

