国密SM4实现表单数据加密传输

SM4加密算法是中国国家密码管理局定义的一种对称分组加密算法,它广泛应用于无线局域网安全协议等领域。

前言

为什么要对前后端传输的表单数据进行加密处理?主要原因有以下几点:

  • 保护隐私和机密性:未经加密的数据在传输过程中容易被黑客、未经授权的第三方监听和截取,导致敏感信息如个人身份、银行账号、商业秘密等泄露,给个人和组织带来严重的安全风险。

  • 防止篡改:未加密的数据可以轻易被中间人修改或插入恶意内容。通过加密,数据的真实性和完整性得以保障,任何对数据的非法更改在解密时都能被发现。

  • 防止数据泄露风险:在传统的表单提交过程中,数据是以明文的形式发送到服务器的。这意味着在数据传输的过程中,如果存在中间人攻击或者网络被监听,那么敏感数据很容易被窃取。

  • 无法保证数据完整性:传统的表单提交是基于HTTP协议的,它使用的是明文传输,不提供数据完整性校验的机制。这就意味着在数据传输过程中,数据可能会被修改、篡改或者替换。

  • 增强数据传输的安全性:加密技术在数据安全中的应用非常广泛,主要包括数据传输加密,使用SSL/TLS等协议对数据进行加密传输,可以确保数据在公网上传输时的安全性。

一、前端加密

在前端加密时,加密的内容可能包含了特殊字符或非ASCII字符。需要先将其转为 UTF-8 或其他标准编码格式的字节数组,再进行 SM4 加密。

<template>
  <div>
    <a-form :form="form" style="margin-top: 20px">
      <a-form-item key="code" v-bind="form" label="编码">
        <a-input placeholder="请输入编码" v-decorator="['description']" />
      </a-form-item>
    </a-form>
  </div>
</template>
  
  <script>
import { getSM2Key, getSMS4Key } from '@/utils/util'
import SM4 from '@/utils/sm4'
export default {
  data() {
    return {
      form: this.$form.createForm(this),
    }
  },
  methods: {
    submitTableForm() {
      const {
        form: { validateFields },
      } = this
      validateFields((errors, values) => {
        if (!errors) {
          const smKey = getSMS4Key.call(this)
          const sm2Key = getSM2Key.call(this, 1)
          formData.description = SG_sm2Encrypt(smKey, sm2Key)
          let codeBytes = new TextEncoder().encode(formData.code)
          formData.description = SM4.encodeByHexSMS4(codeBytes, smKey)
          // 调用接口
          api(formData)
        }
      })
    },
  },
}
</script>
  
  

国密工具类方法如下

/**
 * 获取国密算法秘钥
 * @return String
 */
export function getSMS4Key () {
  return SM4.genRandomKey()
}

/**
 * 获取参数加密传递时所需的sm2公钥,每次登录都重新生成新的公钥
 */
export function getSM2Key (key = 0) {
  let sm2Key
  switch (key) {
    case 1:
      //前台传参时所用密钥,每次登录重新生成
      //添加token标记,避免多次
      let llKey = `${S2}_${sessionStorage.getItem(ACCESS_TOKEN)}`
      sm2Key = Vue.ls.get(llKey) || this.$store.state.user.s2
      break
    case 2:
      //后台传参解密时所需密钥
      // eslint-disable-next-line no-case-declarations
      const s1 = Vue.ls.get(S1) || store.state.user.s1
      sm2Key = Constant.SPRI + s1
      break
    default:
      //用户登录时使用此密钥
      sm2Key = Constant.SPUB
      break
  }
  return sm2Key
}

二、后端解密

通过SM2算法和私钥解密该 decryptKey,获取新的SM4密钥。使用SM4解密算法解密前端传来的字段。中文字符在加密之前被转换成字节流,如果加密或解密时使用了不一致的字符编码(如 UTF-8ISO-8859-1 之间的转换),就会出现乱码。将解密后的数据(ASCII 编码的 JSON 格式)转换为字符。修复可能的字符编码问题,确保解密后的内容正确显示。

    @PostMapping("/edit")
    @LogAnnotation(menuName = MENU_NAME, content = CONTENT, operateType = OperateTypeEnum.UPDATE)
    @ApiOperation(value = "修改数据", httpMethod = "POST")
    @ApiImplicitParam(name = "obj", value = "实体对象", required = true)
    public Result update(@RequestBody @Validated MaterialVO obj) {

        String token = this.getRequest().getHeader(RestConstant.X_ACCESS_TOKEN);
        String priKey = systemCacheUtil.getTokenValue(token, SystemConfigConstant.PRIKEY);
        String sms4Key = systemCacheUtil.getCfgValue(SystemConfigConstant.SECURITY_PROPERTIES, SystemConfigConstant.SMS4);
        if (StrUtil.isNotEmpty(obj.getDecryptKey())){
            sms4Key = Sm2Util.decodeByPriKey(priKey, obj.getDecryptKey());
        }

        String decryptedDescription = Sm4Util.decodeByHex(obj.getDescription(), sms4Key);
        // 解密后的内容是 JSON 格式,包含 ASCII 值
		// 解析解密后的 JSON 字符串
        JSONObject jsonObject = new JSONObject(decryptedDescription);
        StringBuilder finalDescriptionBuilder = new StringBuilder();
        // 遍历 JSON 对象的键
        for (int i = 0; i < jsonObject.length(); i++) {
            // 获取 ASCII 值
            int asciiValue = jsonObject.getInt(String.valueOf(i));
            finalDescriptionBuilder.append((char) asciiValue);
        }
        String finalDescription = finalDescriptionBuilder.toString();
        // 确保解码后的字符串按 UTF-8 解码
        byte[] decryptedBytes = finalDescription.getBytes(StandardCharsets.ISO_8859_1);
        finalDescription = new String(decryptedBytes, StandardCharsets.UTF_8);

        obj.setDescription(finalDescription);



        obj = materialService.update(obj);

        return ResultGenerator.genOkResult(obj);
    }

总结

SM4 是一款高效、安全、符合中国法律和行业标准的对称加密算法,适合国内应用,特别是合规性要求较高的场景。但是国际支持较弱,可能在跨国业务和标准化方面存在兼容性问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

青皮桔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值