密码安全不能只看有没有大写字母、数字和符号。一个看起来“符合规则”的口令,如果容易猜到、曾经泄露,或者在多个网站重复使用,同样可能让账号失守。
从后端开发的角度,我更愿意把它分成两件事:用户如何选择和保管密码,系统如何验证、存储并保护登录过程。
一、哪些密码容易被猜中?
常见弱密码包括简单数字、连续键盘组合、出厂默认口令,以及姓名拼音、手机号、生日、邮箱前缀等个人信息的组合。仅在常见词后加年份或感叹号,也不一定能抵挡规则化猜测。
密码字典可能包含常见口令、历史泄露口令及根据个人信息生成的候选。还有一种不同的攻击叫“撞库”:攻击者拿其他站点泄露的账号密码组合,尝试登录当前站点。因此,强密码一旦复用,也会扩大一次泄露的影响。
二、不要把“8 位加四类字符”当成安全保证
选择密码时,优先考虑足够长、难预测、每个服务独立使用。可以用密码管理器生成并保存随机密码;需要记忆时可选择足够长、不可预测的口令短语,避免名句、个人信息和公开示例。
作为系统策略参考,NIST SP 800-63B-4 对其适用的密码认证场景区分了要求:单因素密码至少 15 个字符;作为多因素认证一部分时可允许最少 8 个字符。它不要求强制混合字符类型,而强调长度、阻止常见或泄露密码等措施。这不是说所有产品只要满足某个长度就绝对安全,也不是所有网站的现行规则。参考 NIST 密码认证要求。
三、用户侧可以做什么?
- 每个网站使用独立密码,尤其要保护邮箱和密码管理器等关键账号。
- 使用可靠的密码管理器,及时处理泄露提醒;确认密码泄露时尽快修改相关账号。
- 启用多因素认证;服务支持时,可以考虑具备抗钓鱼能力的通行密钥或安全密钥。
- 不将密码、恢复码写进公开代码、截图、聊天记录或项目文档,妥善保管恢复方式。
没有泄露迹象时,机械地周期更换密码并不能替代这些措施,反而可能诱使人按固定规律改动。出现泄露、账号异常或其他风险证据时,则应及时处置。
四、系统侧不能只做密码复杂度正则
注册和修改密码时,应结合常见及已泄露口令的阻止列表,不把用户的完整密码交给不可信服务。登录入口还需要限速、异常监测、适当的多因素认证及安全恢复流程,避免无限制尝试。
密码应通过专用的密码哈希方案保存,不保存明文,也不使用单次 MD5、SHA-1 等快速哈希代替密码哈希。PHP 可使用 password_hash()、password_verify(),并在登录成功时按策略判断是否需要重新哈希;算法和参数应结合环境与性能预算选择。
进一步阅读:bcrypt:一种安全的密码哈希函数。密码哈希保护的是存储环节,它不能替代传输加密、访问控制或钓鱼防护。