news 2026/5/28 2:45:20

CryptoJS 核心知识汇总

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CryptoJS 核心知识汇总

CryptoJS 是纯 JavaScript 实现的加密算法库(无需依赖后端),在 CRM 系统中主要用于敏感数据加密(如客户手机号、订单金额、登录密码)、接口参数签名本地存储数据加密等场景。下面从「核心集成→常用加密算法→CRM 实战场景→避坑指南」全维度讲解,贴合 Vue3 + TS 开发。

一、核心定位(CRM 为什么需要加密?)

CRM 系统存储大量敏感商业数据,CryptoJS 解决的核心安全问题:

  1. 本地存储加密:localStorage/sessionStorage 存储的用户信息、筛选条件等,避免明文泄露;
  2. 接口参数签名:请求参数加密 / 签名,防止接口被篡改、抓包伪造请求;
  3. 敏感数据脱敏:客户手机号、身份证号等前端加密后再传给后端;
  4. 临时数据加密:如导出 Excel 的临时密钥、分享链接的参数加密。

CryptoJS 支持的核心算法(CRM 高频使用):

表格

算法类型

用途

示例场景

AES

对称加密(加解密用同一密钥)

本地存储敏感数据、接口参数加密

MD5

哈希摘要(不可逆)

密码加密、参数签名、文件校验

SHA256

哈希摘要(比 MD5 更安全)

重要参数签名、数据完整性校验

HMAC-SHA256

带密钥的哈希(防篡改)

接口请求签名(密钥 + 参数 + 时间戳)

二、快速集成(Vue3 + Vite 项目)

1. 安装依赖

bash

运行

# 核心库(包含所有常用算法) npm install crypto-js -S # TS 类型(可选,需单独安装) npm install @types/crypto-js -D

2. 封装通用加密工具(CRM 首选)

封装统一的加密工具类,避免重复写加密逻辑,同时统一密钥 / 偏移量配置:

typescript

运行

// src/utils/crypto.ts import CryptoJS from 'crypto-js'; // 加密配置(建议从环境变量读取,避免硬编码) const CRYPTO_CONFIG = { // AES 密钥(必须 16/24/32 位,对应 AES-128/AES-192/AES-256) aesKey: import.meta.env.VITE_AES_KEY || 'crm_2026_123456', // AES 偏移量(CBC 模式必填,16 位) aesIv: import.meta.env.VITE_AES_IV || 'crm_iv_12345678', // HMAC 签名密钥 hmacKey: import.meta.env.VITE_HMAC_KEY || 'crm_hmac_2026' }; /** * AES 加密(CBC 模式,兼容后端) * @param data 待加密数据(字符串/对象) * @returns 加密后的 Base64 字符串 */ export const aesEncrypt = (data: string | object): string => { // 统一转为字符串 const dataStr = typeof data === 'object' ? JSON.stringify(data) : data; // 密钥/偏移量转 WordArray const key = CryptoJS.enc.Utf8.parse(CRYPTO_CONFIG.aesKey); const iv = CryptoJS.enc.Utf8.parse(CRYPTO_CONFIG.aesIv); // 加密 const encrypted = CryptoJS.AES.encrypt(dataStr, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 // 后端常用填充方式 }); // 返回 Base64 结果 return encrypted.toString(); }; /** * AES 解密 * @param encryptedStr 加密后的 Base64 字符串 * @returns 解密后的原始数据(字符串/对象) */ export const aesDecrypt = (encryptedStr: string): string | object => { if (!encryptedStr) return ''; const key = CryptoJS.enc.Utf8.parse(CRYPTO_CONFIG.aesKey); const iv = CryptoJS.enc.Utf8.parse(CRYPTO_CONFIG.aesIv); // 解密 const decrypted = CryptoJS.AES.decrypt(encryptedStr, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); // 转 Utf8 字符串 const resultStr = CryptoJS.enc.Utf8.stringify(decrypted); // 尝试解析为对象(失败则返回字符串) try { return JSON.parse(resultStr); } catch { return resultStr; } }; /** * MD5 哈希(不可逆) * @param data 待哈希数据 * @returns 32 位小写哈希值 */ export const md5 = (data: string | object): string => { const dataStr = typeof data === 'object' ? JSON.stringify(data) : data; return CryptoJS.MD5(dataStr).toString().toLowerCase(); }; /** * SHA256 哈希(不可逆) * @param data 待哈希数据 * @returns 64 位小写哈希值 */ export const sha256 = (data: string | object): string => { const dataStr = typeof data === 'object' ? JSON.stringify(data) : data; return CryptoJS.SHA256(dataStr).toString().toLowerCase(); }; /** * HMAC-SHA256 签名(带密钥,防篡改) * @param data 待签名数据(如接口参数) * @returns 签名结果 */ export const hmacSha256 = (data: string | object): string => { const dataStr = typeof data === 'object' ? JSON.stringify(data) : data; const key = CryptoJS.enc.Utf8.parse(CRYPTO_CONFIG.hmacKey); return CryptoJS.HmacSHA256(dataStr, key).toString().toLowerCase(); }; /** * 接口请求签名(参数+时间戳+随机数) * @param params 接口参数 * @returns { params: 加密参数, sign: 签名, timestamp: 时间戳, nonce: 随机数 } */ export const generateApiSign = (params: object) => { const timestamp = Date.now().toString(); const nonce = Math.random().toString(36).substring(2, 10); // 随机数 // 1. 参数排序(避免参数顺序影响签名) const sortedParams = Object.keys(params).sort().reduce((obj, key) => { obj[key] = params[key]; return obj; }, {} as any); // 2. 拼接签名串:参数JSON + 时间戳 + 随机数 const signStr = JSON.stringify(sortedParams) + timestamp + nonce; // 3. 生成签名 const sign = hmacSha256(signStr); // 4. AES 加密参数 const encryptedParams = aesEncrypt(sortedParams); return { params: encryptedParams, sign, timestamp, nonce }; };

三、CRM 实战场景(核心用法)

场景 1:本地存储敏感数据加密

CRM 中用户信息、筛选条件等本地存储需加密,防止明文泄露:

vue

<script setup lang="ts"> import { aesEncrypt, aesDecrypt } from '@/utils/crypto'; // 存储加密后的用户信息 const saveUserInfo = (userInfo) => { const encrypted = aesEncrypt(userInfo); localStorage.setItem('crm-user', encrypted); }; // 读取并解密用户信息 const getUserInfo = () => { const encrypted = localStorage.getItem('crm-user'); return aesDecrypt(encrypted); }; // 使用示例 const userInfo = { id: '123', name: '张三', phone: '13800138000' }; saveUserInfo(userInfo); console.log(getUserInfo()); // { id: '123', name: '张三', phone: '13800138000' } </script>

场景 2:登录密码加密(MD5/SHA256)

密码传输前先做哈希加密(不可逆),避免明文传输:

vue

<script setup lang="ts"> import { md5 } from '@/utils/crypto'; import { useUserStore } from '@/stores/user'; const userStore = useUserStore(); const loginForm = ref({ username: '', password: '' }); const handleLogin = async () => { // 密码 MD5 加密(可加盐:md5(loginForm.value.password + 'crm_salt')) const encryptedPwd = md5(loginForm.value.password); // 传给后端 const res = await userStore.login({ username: loginForm.value.username, password: encryptedPwd }); }; </script>

场景 3:接口请求签名(防篡改)

CRM 核心接口(如订单提交、客户创建)需签名,防止参数被篡改:

vue

<script setup lang="ts"> import { generateApiSign } from '@/utils/crypto'; import axios from '@/utils/axios'; // 提交订单(核心接口) const submitOrder = async (orderData) => { // 1. 生成签名参数 const { params, sign, timestamp, nonce } = generateApiSign(orderData); // 2. 发送请求 const res = await axios.post('/api/order/submit', { params, // 加密后的参数 sign, // 签名 timestamp, // 时间戳 nonce // 随机数 }); return res.data; }; </script>

场景 4:敏感数据脱敏(哈希展示)

客户手机号、身份证号等敏感数据,前端展示哈希后的值(仅用于校验):

vue

<template> <div class="customer-detail"> <p>客户ID:{{ customer.id }}</p> <p>手机号:{{ encryptPhone(customer.phone) }}</p> <p>身份证号:{{ encryptIdCard(customer.idCard) }}</p> </div> </template> <script setup lang="ts"> import { md5 } from '@/utils/crypto'; // 手机号脱敏(保留前3后4,中间哈希) const encryptPhone = (phone) => { if (!phone) return '-'; const prefix = phone.slice(0, 3); const suffix = phone.slice(-4); const middle = md5(phone.slice(3, -4)).slice(0, 4); // 取哈希前4位 return `${prefix}****${suffix}`; }; // 身份证号脱敏 const encryptIdCard = (idCard) => { if (!idCard) return '-'; const prefix = idCard.slice(0, 6); const suffix = idCard.slice(-4); const middle = md5(idCard.slice(6, -4)).slice(0, 8); return `${prefix}********${suffix}`; }; </script>

场景 5:Excel 导出密钥加密

CRM 导出 Excel 时,临时密钥加密后拼接在下载链接中:

vue

<script setup lang="ts"> import { aesEncrypt, aesDecrypt } from '@/utils/crypto'; // 生成导出链接 const generateExportUrl = (params) => { // 1. 加密导出参数 const encryptedParams = aesEncrypt(params); // 2. 拼接链接(后端解密后导出) return `${import.meta.env.VITE_BASE_URL}/api/export?params=${encryptedParams}`; }; // 使用示例 const exportOrder = () => { const params = { startTime: '2026-03-01', endTime: '2026-03-20' }; const url = generateExportUrl(params); window.open(url); // 打开下载链接 }; </script>

四、核心避坑点

1. AES 密钥 / 偏移量长度问题

  • 问题:AES 密钥长度必须是 16/24/32 位(对应 128/192/256 位加密),否则加密失败;
  • 解决方案:
    1. 环境变量配置的密钥严格按长度设置(如 16 位:VITE_AES_KEY=1234567890123456);
    2. 若后端密钥长度不符,可截取 / 补位:CryptoJS.enc.Utf8.parse(key).toString().substring(0,16)

2. 前后端加密模式 / 填充方式不一致

  • 问题:前端 CBC 模式 + Pkcs7 填充,后端 ECB 模式 + NoPadding,导致解密失败;
  • 解决方案:
    1. 与后端统一:推荐 CBC 模式 + Pkcs7 填充(通用方案);
    2. 禁用 ECB 模式(ECB 无偏移量,安全性低)。

3. 中文乱码问题

  • 问题:加密 / 解密后中文变成乱码;
  • 解决方案:
    1. 统一使用CryptoJS.enc.Utf8编码(不要用 Latin1);
    2. 对象加密前先JSON.stringify,解密后JSON.parse

4. MD5 加密后大小写不一致

  • 问题:前端 MD5 结果大写,后端小写,导致校验失败;
  • 解决方案:统一转为小写(toString().toLowerCase())。

5. 本地存储加密密钥泄露

  • 问题:密钥硬编码在代码中,可通过打包后的 JS 文件反编译获取;
  • 解决方案:
    1. 密钥从后端接口动态获取(首次登录后返回);
    2. 密钥分片存储(如一部分在代码,一部分在本地存储);
    3. 生产环境混淆代码(如 Terser 压缩)。

五、总结(CRM 开发最佳实践)

  1. 封装统一工具:将加密逻辑封装为全局工具函数,避免重复代码,统一密钥 / 算法配置;
  2. 按需选择算法
    • 本地存储 / 参数加密:用 AES 对称加密;
    • 密码 / 签名:用 MD5/SHA256 哈希(不可逆);
    • 接口防篡改:用 HMAC-SHA256 带密钥签名;
  1. 安全注意事项
    • 密钥不要硬编码,优先从环境变量 / 后端接口获取;
    • 核心接口必须签名 + 时间戳 + 随机数,防止重放攻击;
    • 本地存储敏感数据必须加密,避免 XSS 泄露;
  1. 前后端对齐
    • 统一加密算法、模式、填充方式、编码格式;
    • 测试阶段先做加密 / 解密联调,避免上线后兼容问题。

CryptoJS 是 CRM 系统前端加密的 “标配工具”,只需掌握 AES/MD5/HMAC-SHA256 三种核心算法,就能覆盖 99% 的加密场景;封装后的工具类可直接复用,兼顾安全性与开发效率。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 2:42:51

AI 智能打草机高效低功耗 MOSFET 完整选型方案

随着 AI 技术在户外园林工具中的普及&#xff08;如智能路径规划、障碍物识别、自适应切割&#xff09;&#xff0c;打草机对功率 MOSFET 提出更高要求&#xff1a;高效率、低功耗、高集成度。微碧半导体&#xff08;VBsemi&#xff09;基于先进的 Trench 工艺&#xff0c;为您…

作者头像 李华
网站建设 2026/5/28 2:39:14

在Node.js后端服务中集成Taotoken实现多模型智能路由

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 在Node.js后端服务中集成Taotoken实现多模型智能路由 应用场景类&#xff0c;针对Node.js后端开发者&#xff0c;场景描述如何根据…

作者头像 李华
网站建设 2026/5/28 2:38:50

嘉兴南湖区腹直肌分离,亲测有效的锻炼方法分享

引言随着现代生活方式的变化&#xff0c;越来越多的人开始关注自身健康与体态管理。在嘉兴南湖区&#xff0c;许多朋友可能遇到了腹直肌分离的问题&#xff0c;这不仅影响美观还可能带来健康隐患。本文将基于科学原理和实践经验&#xff0c;分享几种有效改善腹直肌分离的锻炼方…

作者头像 李华
网站建设 2026/5/28 2:38:43

服装连锁店库存软件怎么选?分色分码管理是关键

服装连锁店选择库存管理软件&#xff0c;核心在于按门店规模匹配功能需求。分色分码精细管理、多店实时库存同步、智能预警补货是三大关键决策维度&#xff0c;有赞 零售连锁、秦丝进销存、百胜软件、管家婆等方案各有侧重&#xff0c;商家应结合自身业态优先试用再做决定。库存…

作者头像 李华
网站建设 2026/5/28 2:37:54

告别椒盐噪声:FPGA并行排序算法实现中值滤波的吞吐量优化指南

FPGA并行排序算法在中值滤波中的吞吐量优化实战 当处理高分辨率图像时&#xff0c;传统的中值滤波算法往往面临吞吐量瓶颈。我曾在一个医疗影像处理项目中&#xff0c;面对4K内窥镜视频的实时降噪需求&#xff0c;深刻体会到优化算法硬件实现的重要性。本文将分享如何通过FPGA并…

作者头像 李华