密码强度、一致性、相似度校验

需求

  1. 校验原密码与数据库密码是否一致
  2. 新密码强度校验
    1. 密码复杂度: 至少包含大小写字母、至少包含数字、至少包含特殊字符(如 !@#$%^&*)、至少8个字符长度
    2. 不能与最近10个密码相同
    3. 不能与最近10个密码相似度超过25%

注意❗️ 所有涉及密码的敏感操作(如验证原密码、历史密码比对)都应由后端完成。前端仅能做 辅助性预校验,如复杂度、相似度校验,不能替代后端安全逻辑。

需求1校验原密码是否正确

因为前端无法访问数据库中的加密密码,如果后端返回明文或可逆加密的历史密码给前端用于比较,这是 严重的安全漏洞 ,所以应该由 用户输入旧密码 → 发送到后端 → 后端验证是否一致 如果不一致 → 返回错误码

需求2-1密码复杂度校验

javascript 复制代码
function validatePasswordStrength(password) {
  const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/;
  return regex.test(password);
}

if (!validatePasswordStrength(newPassword)) {
  return 'PASSWD_SIMPLE=密码至少包含大小写字母、数字和特殊符号,至少8个字。';
}

需求2-2不能与最近10个密码相同

实际开发中应由后端实现。如果前端实现,需后端提供历史密码,且是加密后的,前端可以做一些简单比较。

javascript 复制代码
function isNewPassEqualOld(newPass, historyPasswords) { 
    return historyPasswords.includes(newPass); // 或者 hash 比较 
}

需求2-31不能与最近10个密码相似度超过25%

一、什么是密码相似度?

密码相似度 是指两个字符串之间在内容和结构上的相似程度。通常用一个百分比值来表示,0% 表示完全不同,100% 表示完全相同。

二、应用场景:

  • 防止用户设置的新密码与最近使用的旧密码太像。
  • 提高密码安全性,避免用户只是轻微修改旧密码(如 abc123abc124)。
  • 在修改密码时,系统要求"新密码不能与最近设置的10个密码相似度超过25%"。

三、判断密码相似度?

✅ 1. Levenshtein 编辑距离(适合短密码)

原理:

  • 计算将一个字符串转换为另一个字符串所需的最少单字符编辑操作(插入、删除、替换)的数量。
  • 距离越小,相似度越高。
ini 复制代码
function levenshtein(s, t) {
  const m = s.length;
  const n = t.length;
  const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));

  for (let i = 0; i <= m; i++) dp[i][0] = i;
  for (let j = 0; j <= n; j++) dp[0][j] = j;

  for (let i = 1; i <= m; i++) {
    for (let j = 1; j <= n; j++) {
      if (s[i - 1] === t[j - 1]) {
        dp[i][j] = dp[i - 1][j - 1];
      } else {
        dp[i][j] = Math.min(
          dp[i - 1][j] + 1,   // 删除
          dp[i][j - 1] + 1,   // 插入
          dp[i - 1][j - 1] + 1 // 替换
        );
      }
    }
  }

  return dp[m][n];
}

// 相似度百分比(0~1)
function similarityPercentage(s1, s2) {
  const longer = s1.length > s2.length ? s1 : s2;
  const shorter = s1.length <= s2.length ? s1 : s2;
  const distance = levenshtein(longer, shorter);
  return 1 - distance / longer.length;
}
arduino 复制代码
console.log(similarityPercentage("abc123", "abc124")); // 输出:0.833
✅ 2. Jaro-Winkler 相似度算法

原理:

  • 主要用于比较姓名等短字符串。
  • 注重字符顺序的匹配。
  • 对于前缀相同的字符串,会给予额外加分。

使用第三方库 (推荐使用)

c 复制代码
npm install string-similarity
javascript 复制代码
import { compareTwoStrings } from 'string-similarity';

const similarity = compareTwoStrings("abc123", "abc124"); // 返回 0~1 的相似度
console.log(similarity); // 输出约 0.9167

总结

密码检查项分工,但为了安全起见:

  • 与历史密码是否一致,应由后端处理
  • 与历史密码相似度是否过高,推荐后端做
  • 密码强度检查,前后端都做
相关推荐
ywf12152 小时前
前端的dist包放到后端springboot项目下一起打包
前端·spring boot·后端
恋猫de小郭2 小时前
2026,Android Compose 终于支持 Hot Reload 了,但是收费
android·前端·flutter
hpoenixf8 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特8 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷8 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian9 小时前
前端node常用配置
前端
华洛9 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq9 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A10 小时前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常10 小时前
被EdgeToEdge适配折磨疯了,谁懂!
前端