zxcvbn是当前前端最靠谱的密码强度实时检测方案,基于泄露库、常见模式和熵值估算,支持传入用户名/邮箱辅助判断,需关注feedback.warning而非仅score阈值。

用 zxcvbn 库实时检测密码强度最靠谱
浏览器原生不提供弱口令判断逻辑,pattern 或正则只能做简单格式校验(比如“至少8位+大小写字母”,但无法识别 password123 这种典型弱口令)。真正能评估“人类实际破解难度”的,目前只有 zxcvbn —— 它基于真实泄露密码库、常见模式(键盘序列、年份、姓名变体等)和熵值估算,不是规则堆砌。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 直接通过 CDN 引入:
<script src="https://cdnjs.cloudflare.com/ajax/libs/zxcvbn/4.4.2/zxcvbn.js"></script>(v4.4.2 兼容性好,体积小) - 监听输入框的
input事件,避免用blur——用户需要即时反馈,不是提交时才提醒 - 别直接调用
zxcvbn(password)后就显示“弱/中/强”:它的score是 0–4,但 0 和 1 都算危险,2 才勉强可用,3–4 才算较安全;更关键的是看feedback.suggestions和feedback.warning字段,它们才是用户能听懂的提示
zxcvbn 的输入要不要清洗?怎么传用户名/邮箱辅助判断
zxcvbn 默认只分析密码字符串本身,但现实中很多弱口令来自“用户名+123”“邮箱前缀+年份”。它支持传入第二个参数 user_inputs(数组),把关联信息喂给算法,让它主动避开这些组合。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 如果页面已有用户名或邮箱字段,取其值(如
document.getElementById('username').value)并塞进user_inputs数组里,例如:zxcvbn(pwd, [username, email.split('@')[0]]) - 不要传空字符串或 null 到
user_inputs,会触发内部报错;先做if (username) inputs.push(username) - 别传整个邮箱地址(含 @ 符号),
zxcvbn对特殊符号处理不稳定;取本地部分(email.split('@')[0])更稳妥
为什么输入 12345678 返回 score=0,但 123456789 却是 score=2?
这不是 bug,是设计:它把连续数字序列当作“基础模式”而非单纯长度判断。12345678 被识别为“ascending sequence”,长度刚好在易爆破阈值内;而加一位变成 123456789,虽然还是序列,但熵值提升、常见度下降,算法认为暴力破解成本略高。
这意味着:
- 不能只依赖
score >= 2就放行——要结合feedback.warning。比如zxcvbn('iloveyou')得分是 1,但警告是“常见单词”,比纯数字更需拦截 - 别自己改 score 阈值(比如强行要求 ≥3)。很多真实场景下,用户记不住 3 分密码,反而去写纸条;平衡点常设在 score ≥ 2 且
feedback.warning === '' - 移动端软键盘常自动首字母大写,用户输
password实际可能提交Password——测试时务必用真实输入流,别只 copy-paste
不用 zxcvbn 的替代方案有哪些坑
有人图省事用正则或自写规则,比如 /(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}/,但这根本防不住 Tr0ub4dor&3(xkcd 经典例子)或 Qwerty123。
常见翻车点:
- 用
Entropy计算公式(如 -log₂(字符集^长度)):数学上没错,但完全忽略人类行为——aaaaaaab熵值很高,实际一秒钟就被字典攻击拿下 - 调用后端接口查黑名单:延迟高、暴露用户输入意图、增加服务器负担;弱口令检测必须在前端完成,后端只做最终校验
- 误信某些 npm 包(如
password-strength-meter):它们只是包装了简单规则,没集成泄露库,对sunshine2023这类“语义弱口令”毫无反应
真正绕不开的复杂点只有一个:你得接受 zxcvbn 的判断结果,而不是试图用“更短的代码”或“更快的正则”去覆盖它。它不是完美,但已是当前前端能做到的最贴近真实风险的方案。











