SM2国密算法加解密

简介: 接口安全设计原则的一个点就是数据不能明文传输,除了https这个必须的请求外,接口数据加密也是一个重要的方式,下面介绍一下SM2国密算法加解密的使用方式
接口安全设计原则的一个点就是数据不能明文传输,除了https这个必须的请求外,接口数据加密也是一个重要的方式,下面介绍一下SM2国密算法加解密的使用方式。

这里我就针对目前前后端分离架构的方式来简单介绍一下如何正确使用SM2算法对数据进行加解密,介绍分为后端加解密和前端加解密。

1.后端加解密

1.1 导入POM依赖

<!-- hutool -->
<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.8.5</version>
</dependency>
<!-- 加解密依赖包 -->
<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk15to18</artifactId>
  <version>1.71</version>
</dependency>

1.2 生成公钥、私钥密钥对

/**
 * 生成公钥、私钥,这个保存好,尤其是私钥,切记不可泄漏
 */
public static void generateCommonKey() {
  SM2 sm2 = SmUtil.sm2();
  // 私钥:这个保存好,切记不要泄漏,真的泄露了就重新生成一下
  byte[] privateKey = BCUtil.encodeECPrivateKey(sm2.getPrivateKey());
  // 公钥:这个是前后端加密用的,不压缩选择带04的,不带04到时候前端会报错
  byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);
  Console.log("公钥:\n{}", HexUtil.encodeHexStr(publicKey));
  Console.log("私钥:\n{}", HexUtil.encodeHexStr(privateKey));
}

1.3 加解密

/**
 * sm2明文加密
 * PRIVATE_KEY:生成的私钥
 * PUBLIC_KEY:生成的公钥
 * @param data 加密前的明文
 * @return 加密后的密文
 */
public static String encryptData(String data) {
  SM2 sm2 = SmUtil.sm2(ECKeyUtil.toSm2PrivateParams(PRIVATE_KEY), ECKeyUtil.toSm2PublicParams(PUBLIC_KEY));
  String encryptBcd = sm2.encryptBcd(data, KeyType.PublicKey);
  // 这里的处理前端也可以处理,这个就看怎么约定了,其实都无伤大雅
  if (StrUtil.isNotBlank(encryptBcd)) {
    // 生成的加密密文会带04,因为前端sm-crypto默认的是1-C1C3C2模式,这里需去除04才能正常解密
    if (encryptBcd.startsWith("04")) {
      encryptBcd = encryptBcd.substring(2);
    }
    // 前端解密时只能解纯小写形式的16进制数据,这里需要将所有大写字母转化为小写
    encryptBcd = encryptBcd.toLowerCase();
  }
  return encryptBcd;
}

/**
 * sm2密文解密
 * PRIVATE_KEY:生成的私钥
 * PUBLIC_KEY:生成的公钥
 * @param encryptData 加密密文
 * @return 解密后的明文字符串
 */
public static String decryptData(String encryptData) throws Exception {
  if (StrUtil.isBlank(encryptData)) {
    throw new RuntimeException("解密串为空,解密失败");
  }
  SM2 sm2 = SmUtil.sm2(ECKeyUtil.toSm2PrivateParams(PRIVATE_KEY), ECKeyUtil.toSm2PublicParams(PUBLIC_KEY));
  // BC库解密时密文开头必须带04,如果没带04则需补齐
  if (!encryptData.startsWith("04")) {
    encryptData = "04".concat(encryptData);
  }
  byte[] decryptFromBcd = sm2.decryptFromBcd(encryptData, KeyType.PrivateKey);
  if (decryptFromBcd != null && decryptFromBcd.length > 0) {
    return StrUtil.utf8Str(decryptFromBcd);
  } else {
    throw new Exception("密文解密失败");
  }
}

2.前端加解密

2.1 安装NPM包依赖

npm install --save sm-crypto

2.2 新建公共sm2.js

const sm2 = require('sm-crypto').sm2;
// 加密策略,1 - C1C3C2,0 - C1C2C3,默认为1
const encryptMode = 1;
const publicUiKey = '后端生成的公钥';
const privateKey = '后端生成的私钥';

/**
 * 加密数据
 * @param {Object} data 明文数据
 */
export function encryptData(data) {
    if (data && (typeof data === 'string') && (data.constructor === String)) {
        return '04'.concat(sm2.doEncrypt(data, publicUiKey, encryptMode));
    }
    return data;
}


/**
 * 加密对象数据
 * @param {Object} data 对象明文
 */
export function encryptObjectData(data) {
    if (data) {
        return '04'.concat(sm2.doEncrypt(JSON.stringify(data), publicUiKey, encryptMode));
    }
    return data;
}

/**
 * 解密数据
 * @param {Object} dataHex 加密的密文数据
 */
export function decryptData(encryptData) {
    if (encryptData && (typeof encryptData === 'string') && (encryptData.constructor === String)) {
        const decryptData = sm2.doDecrypt(encryptData, privateKey, encryptMode);
        return decryptData;
    }
}

2.3 使用

import { encryptData, decryptData} from "../../../request/sm2.js";
encryptData('明文');
decryptData('密文');

3.参考文档

https://www.npmjs.com/package/sm-crypto

目录
相关文章
|
8月前
|
算法 测试技术 Go
go-dongle v1.1.7 发布,新增 SM4 国密分组对称加密算法支持
`dongle` 是一款轻量级、语义化、开发者友好的 Golang 密码库,100% 单元测试覆盖,获 2024 年 GVP 与 G-Star 双项荣誉。支持 SM4 国密算法,提供标准及流式处理,优化读取位置重置,提升安全性与易用性。文档齐全,开源免费,欢迎 Star!
413 0
|
8月前
|
算法 测试技术 Go
go-dongle v1.1.7 发布,新增 SM4 国密分组对称加密算法支持
`dongle` 是一款轻量级、语义化、开发者友好的 Golang 密码库,100% 单元测试覆盖,获 2024 年 GVP 与 G-Star 双项荣誉。支持 SM4 国密算法,提供标准及流式处理,优化读取位置重置,提升安全性与易用性。文档齐全,开源免费,欢迎 Star!
373 0
|
算法 安全 Java
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
【4月更文挑战第28天】性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
1307 1
性能工具之 JMeter 自定义 Java Sampler 支持国密 SM2 算法
|
算法 安全 物联网
关于SM2、SM3、SM4、SM9这四种国密算法
本文介绍了四种国密算法——SM2、SM3、SM4和SM9。SM2是一种基于椭圆曲线的非对称加密算法,用于数据加密和数字签名;SM3是哈希算法,用于数字签名和消息完整性验证;SM4是对称加密算法,用于数据加密和解密;SM9是基于标识的非对称密码算法,适用于物联网环境中的数据安全和隐私保护。
11516 121
|
算法 安全 物联网
如何应用SM2算法进行身份认证
【10月更文挑战第5天】如何应用SM2算法进行身份认证
1133 1
|
存储 算法 安全
SM2算法的应用场景有哪些?
【10月更文挑战第5天】SM2算法的应用场景有哪些?
1529 1
|
存储 算法 安全
超级好用的C++实用库之国密sm4算法
超级好用的C++实用库之国密sm4算法
1288 0
|
算法 安全 Java
深入解析ECC(椭圆曲线密码学)加解密算法
深入解析ECC(椭圆曲线密码学)加解密算法
深入解析ECC(椭圆曲线密码学)加解密算法
|
算法 安全 Java
AES加解密算法:原理、应用与安全性解析
AES加解密算法:原理、应用与安全性解析

热门文章

最新文章