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

需求

  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

总结

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

  • 与历史密码是否一致,应由后端处理
  • 与历史密码相似度是否过高,推荐后端做
  • 密码强度检查,前后端都做
相关推荐
lexiangqicheng13 分钟前
es6+和css3新增的特性有哪些
前端·es6·css3
拉不动的猪1 小时前
都25年啦,还有谁分不清双向绑定原理,响应式原理、v-model实现原理
前端·javascript·vue.js
烛阴1 小时前
Python枚举类Enum超详细入门与进阶全攻略
前端·python
孟孟~1 小时前
npm run dev 报错:Error: error:0308010C:digital envelope routines::unsupported
前端·npm·node.js
孟孟~1 小时前
npm install 报错:npm error: ...node_modules\deasync npm error command failed
前端·npm·node.js
狂炫一碗大米饭1 小时前
一文打通TypeScript 泛型
前端·javascript·typescript
wh_xia_jun1 小时前
在 Spring Boot 中使用 JSP
java·前端·spring boot
二十雨辰2 小时前
[HTML5]快速掌握canvas
前端·html
tingkeiii2 小时前
【react+antd+vite】优雅的引入svg和阿里巴巴图标
前端·react.js·前端框架
清幽竹客2 小时前
vue-18(使用 Vuex 插件实现高级功能)
前端·vue.js·前端框架·vue