
概述
随着信息安全法规日益严格,如《网络安全法》《数据安全法》和等保三级的落实,前后端通信中的敏感数据必须在传输层之上再加一层“国产加密”,才能满足合规与防护需求。接下来将以 SM2 与 SM4 为核心,详细剖析前端请求、后端处理及响应加密的全流程,并附示例代码,帮助读者快速落地。
一、背景与法规要求
法规要求:
- 《网络安全法》《数据安全法》强调敏感数据加密存储与传输;
- 等保三级对“重要信息系统”提出应用层加密需求。
国产算法优势:
- SM2/SM4 系列为国家密码算法,已标准化并广泛验证;
- 与通用算法(AES/RSA)兼容,便于渐进式升级。
二、算法选型
算法 | 类型 | 作用 | 备注 |
---|---|---|---|
SM2 | 非对称 | 用于交换对称密钥 | 安全性强、计算效率适中 |
SM4 | 对称 | 用于加密具体业务数据 | 性能优异,适合大数据量传输 |
AES | 对称 | 兼容场景下的通用方案 | 跨平台生态良好,可做备用或过渡方案 |
三、核心流程
阶段 | 前端操作 | 后端操作 |
---|---|---|
初始化 | 拉取后端 SM2 公钥 | 生成 SM2 密钥对,并提供公钥接口 |
请求发送 | 1. 生成随机 SM4 密钥 2. 用 SM4 加密业务数据 3. 用 SM2 公钥加密 SM4 密钥 4. 组装请求体 |
1. 用私钥解密获得 SM4 密钥 2. 用 SM4 解密业务数据 3. 业务处理 |
响应返回 | — | 1. 用 SM4 加密响应 JSON 2. 可选:用私钥再 SM2 加密 SM4 密钥 3. 返回密文 |
前端解析 | 1. (可选)用 SM2 公钥/私钥解密 SM4 密钥 2. 用 SM4 解密响应体 |
— |
四、前端实现要点(伪代码)
公钥获取与存储
// 初始化时调用 async function fetchPublicKey() { const { data: { sm2PublicKey } } = await axios.get('/api/crypto/pubkey'); // 建议存储在 Pinia 或 context 中 store.commit('crypto/setPublicKey', sm2PublicKey); // 如需持久化,可选 localStorage localStorage.setItem('sm2PublicKey', sm2PublicKey); }
一次性 SM4 密钥生成
import SM4 from 'sm-crypto/lib/sm4'; function generateSM4Key() { // 16 字节随机密钥 return window.crypto.getRandomValues(new Uint8Array(16)).join(''); }
业务数据与密钥加密
import SM2 from 'sm-crypto/lib/sm2'; async function encryptRequest(payload) { const sm4Key = generateSM4Key(); const sm2Pub = store.state.crypto.sm2PublicKey; const encryptedData = SM4.encrypt(JSON.stringify(payload), sm4Key); const encryptedKey = SM2.doEncrypt(sm4Key, sm2Pub); return { encryptedKey, encryptedData }; }
封装与发送
async function sendSecureRequest(api, payload) { const { encryptedKey, encryptedData } = await encryptRequest(payload); return axios.post(api, { key: encryptedKey, data: encryptedData }); }
五、后端实现要点(伪代码)
以 Spring Boot 为例:
推荐使用Interceptor,这里仅是演示
@RestController
@RequestMapping("/api/secure")
public class SecureController {
@Value("${crypto.sm2.private-key}")
private String sm2PrivateKey;
@PostMapping("/process")
public ResponseEntity<?> process(@RequestBody SecurePayload payload) {
// 1. 解密 SM4 密钥
String sm4Key = SM2.decrypt(payload.getKey(), sm2PrivateKey);
// 2. 解密业务数据
String json = SM4.decrypt(payload.getData(), sm4Key);
BusinessRequest req = objectMapper.readValue(json, BusinessRequest.class);
// 3. 业务处理...
BusinessResponse resp = service.handle(req);
// 4. 加密响应
String respJson = objectMapper.writeValueAsString(resp);
String encryptedData = SM4.encrypt(respJson, sm4Key);
return ResponseEntity.ok(Map.of("data", encryptedData));
}
}
Tip:如需双向加密,可在响应里同时返回
encryptedKey: SM2.encrypt(sm4Key, clientPubKey)
。
六、公钥存储策略
- 短期存储:Vue/Pinia 中维护,方便统一调用;
- 持久化:
localStorage/sessionStorage
,防止页面刷新导致丢失; - 安全性:SM2 公钥非机密,可安全保存在前端。
七、全流程示例图
八、总结与最佳实践
- 密钥管理:后端妥善存储 SM2 私钥,使用 HSM 或环境变量;
- 性能优化:SM4 加解密速度快,SM2 仅用于短字符串,加密开销可接受;
- 兼容性:可与 AES/RSA 并行使用,逐步迁移;
- 安全防护:配合 HTTPS,防止中间人;做好重放攻击检测(如加时间戳、随机串)。
推荐
https://gitee.com/lab1024/smart-admin
SmartAdmin 由 中国·洛阳 1024创新实验室 基于SpringBoot2/3+Sa-Token+Mybatis-Plus 和 Vue3+Ant Design Vue+Uni-App+Uni-UI,并以 「高质量代码」为核心,「简洁、高效、安全」的快速开发平台。
国内首个满足《网络安全-三级等保》、《数据安全》 功能要求,支持登录限制、接口国产加解密、数据脱敏等一系列安全要求。
前端提供 JavaScript和TypeScript双版本,后端提供 Java8+SpringBoot2.X和Java17+SpringBoot3.X 双版本。
同时 重磅开源 开源六年来 千余家企业验证过且正在使用 的代码规范: 《高质量代码思想》、《Vue3规范》、《Java规范》 ,让大家在这浮躁的世界里感受到一股把代码写好的清流!同时又能节省大量时间,减少加班,快乐工作,保持谦逊,保持学习,热爱代码,更热爱生活 !