应选用 js-md5 而非 crypto-js,因其纯 JS 实现、无 crypto 依赖、全端兼容、体积仅约 3KB;crypto-js 全量引入会导致小程序报错且多端加密结果不一致。

直接用 js-md5,别自己抄 MD5 函数或塞一个几十 KB 的 crypto-js 全量包进去——后者在小程序里大概率报 Cannot find module 'crypto',App 端加密结果还可能和 H5 不一致。
为什么选 js-md5 而不是 crypto-js
js-md5 是纯 JS 实现,无 Node.js 依赖,H5 / 微信小程序 / App(v2/v3)全端跑得稳;体积仅约 3KB,不拖慢首屏。而 crypto-js 默认引入会依赖 crypto 模块,在 uni-app 多端运行时根本不存在,必须精确到子模块(如 import MD5 from 'crypto-js/md5'),稍一松懈就报错或加密错位。
- 常见错误现象:
crypto-js在微信小程序里提示Cannot find module 'crypto';H5 加密结果和 App 端对不上 - 如果你只做 MD5,
js-md5是更轻、更稳、更省心的选择 - 真要 AES 加解密,再单独引入
crypto-js/aes子模块,避免全量加载
安装与全局挂载最省事
在项目根目录执行:npm install js-md5 -D,然后进 main.js(uni-app v2)或 main.ts(v3)统一挂载:
import md5 from 'js-md5' // v2 Vue.prototype.$md5 = md5 // v3(createSSRApp 后) const app = createSSRApp(App) app.config.globalProperties.$md5 = md5
之后所有 Vue 页面里直接用 this.$md5('123456'),不用每个文件重复 import。注意:nvue 页面不共享 Vue 实例上下文,仍需局部 import md5 from 'js-md5'。
MD5 加盐是硬性要求,不加等于没加
裸调 this.$md5(this.password) 是典型安全反模式。'123456' 的 MD5 值全球通用,彩虹表秒破。后端一般要求前端至少拼接动态盐值,再传给服务端二次哈希。
- 盐不能写死,比如
md5(password + 'abc')—— 盐泄露即全量密码失效 - 推荐组合方式:
const salt = this.username + Date.now().toString().slice(-6) + uni.getSystemInfoSync().deviceId?.slice(-4) || '' - 最终加密:
const hash = this.$md5(this.password + salt),且必须把salt和hash一起发给后端校验 - 若后端要求 hex 小写输出(默认),无需额外处理;若需大写,
md5.hex_md5()不可用 ——js-md5不提供该 API,改用md5(value).toUpperCase()
nvue 页面和条件编译的坑
nvue 页面不走 Vue 运行时,this.$md5 无效,必须手动 import md5 from 'js-md5';如果项目同时存在 vue + nvue 页面,别指望一套挂载逻辑全覆盖。
另外,某些老项目用的是手动下载的 md5.js 文件(比如从博客复制的 100+ 行实现),这类代码往往不兼容 Unicode 字符(中文密码会出错),且无维护、无测试。优先删掉,换 js-md5 npm 包。
真正容易被忽略的是:盐值生成逻辑必须前后端对齐,哪怕只是时间戳截取位数、设备 ID 取哪几位,差一位整个签名就验不过——别只测 H5,小程序和 App 端务必实机验证。


















