基于国密 SM3/SM4/SM2 的前后端数据完整性校验实战(附完整代码)

基于国密 SM3/SM4/SM2 的前后端数据完整性校验实战(附完整代码)

在这里插入图片描述

在政务、金融、电力等关键领域,数据在传输过程中不仅要保证机密性(不被窃取),还要保证完整性(不被篡改)。国密算法(SM2/SM3/SM4)作为国内标准,正被越来越多项目采用。本文将以一个真实项目中的前端代码为例,深入解析如何利用 SM2、SM4、SM3 实现一套完整的请求加密与数据完整性校验方案,并提供可直接复用的核心代码与实现思路。

一、为什么需要“加密+完整性校验”?

  • 加密(SM4):保证数据不会被中间人看到,解决机密性问题。
  • 完整性校验(SM3):保证数据在传输过程中没有被篡改,解决防篡改问题。
  • 密钥安全交换(SM2):使用非对称加密安全传递对称密钥,避免密钥暴露。

三者结合,形成了一套端到端的安全通信机制,即使在 HTTPS 之外也能提供额外保护。

二、整体架构与数据流

前端                                                      后端
1. 生成 SM4 密钥(key)和 IV
2. 用 SM2 公钥加密 key 和 IV → 放入请求头
3. 用 SM4 加密业务数据 → 得到密文 body
4. 用 SM3 计算密文的哈希 → 放入请求头
5. 生成 timestamp + nonce,SM3 签名 → 放入请求头
6. 发送请求(头 + 密文body)
                                                        7. 用 SM2 私钥解密出 SM4 密钥
                                                        8. 校验 timestamp 和 nonce(防重放)
                                                        9. 用 SM3 校验密文完整性
                                                        10. 用 SM4 解密得到业务数据
                                                        11. 处理业务,返回响应(同样加密+完整性)
12. 收到响应,校验响应完整性,解密得到业务数据

三、前端核心代码解析(基于 Axios 拦截器)

以下代码来自真实项目,我将逐段解释其核心逻辑。

3.1 国密库引入与配置

import {
   
    sm4 as SM4 } from 'gm-crypt'
// 假设 smEncrypt 是一个封装了 SM2/SM3 的全局对象
const sm3 = smEncrypt.sm3

说明gm-crypt 是 Node.js 环境下常用的 SM4 加密库;smEncrypt 通常来自第三方国密 SDK,提供 SM2 加密和 SM3 哈希方法。实际开发中可根据技术栈选择对应的库(如 sm-crypto)。

3.2 生成随机字符串与签名头(防重放)

/** 生成12位不重复随机字符串(用于 X-Nonce) */
const getUniqueNonce = () => {
   
   
  const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  const arr = $chars.split('')
  for (let i = arr.length - 1; i > 0; i--) {
   
   
    const j = Math.floor(Math.random() * (i + 1));
    [arr[i], arr[j]] = [arr[j], arr[i]]
  }
  return arr.slice(0, 12).join('')
}

/** 生成请求签名头 X-Timestamp、X-Nonce、X-Signature */
const getSignatureHeaders = () => {
   
   
  const timestamp = Date.now().toString()
  const nonce = getUniqueNonce()
  const signature = sm3(timestamp + nonce)   // SM3 签名
  return {
   
   
    'X-Timestamp': timestamp,
    'X-Nonce': nonce,
    'X-Signature': signature
  }
}

核心要点

  • 时间戳 + 随机数拼接后做 SM3 哈希,得到签名。
  • 后端会校验时间戳是否在允许范围内(如5分钟),并检查 nonce 是否已被使用(需用 Redis 缓存),从而防止重放攻击。

3.3 动态生成 SM4 密钥与 IV,并用 SM2 公钥加密

const getAesKey = function (len = 32) {
   
   
  const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
  const maxPos = $chars.length
  let keyStr = ''
  for (let i = 0; i < len; i++) {
   
   
    keyStr += $chars.charAt(Math.floor(Math.random() * maxPos))
  }
  return keyStr
}

const aeskey = getAesKey().substring(0, 16)   // SM4 密钥(16字节)
const aesiv = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二川bro

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值