Vue+Springboot 前后端完整使⽤国密算法SM2数据加密传输交互完整解决⽅案项⽬外⽹部署的时候经常会有要求数据加密传输的情况,特别是企事业单位的项⽬,另为安全或者红头⽂件计,经常要求使⽤国密算法,因为涉及交互,所以使⽤SM2⾮对称加密。
后端(Springboot )
(1)所需主要依赖(其他如有缺失⾃⾏百度即可):
(2)SM2功能⽅法的创建
博主这⾥在后端把相关的加解密功能做成了功能接⼝,所以这⾥直接展⽰service实现类的代码,⾥边的统⼀返回参数改成⾃⼰的类型即可        <!-- hutool ⼯具类 -->        <dependency>            <groupId>cn.hutool</groupId>            <artifactId>hutool-all</artifactId>            <version>5.3.10</version>        </dependency>        <!-- 第三⽅加密功能依赖 -->        <dependency>            <groupId>org.bouncycastle</groupId>            <artifactId>bcprov-jdk15to18</artifactId>            <version>1.68</version>        </dependency>
1
2
3
springboot推荐算法4
5
6
7
8
9
10
11
12
13import util.CharsetUtil;import util.HexUtil;import util.Ra
ndomUtil;import util.StrUtil;import pto.BCUtil;import pto.SmUtil;import pto.asymmetric.KeyType;import pto.asymmetric.SM2;import pto.symmetric.SymmetricCrypto;import stant.EncryptConstant;import ption.base.BaseException;import com.pt.dto.ApiEncryptInfoDTO;import com.pt.dto.Result;import com.pt.service.ApiEncryptService;slf4j.Slf4j;import org.apachemons.lang3.StringUtils;import ines.SM2Engine;import pto.params.ECPrivateKeyParameters;import pto.params.ECPublicKeyParameters;import org.bouncycastle.jcajce.BCECPublicKey;import org.springframework.stereotype.Service;/** * 加解密相关功能实现类 * * @author gbx  */@Service @Slf4j public class ApiEncryptServiceImpl implements ApiEncryptService {    /**    * SM2加密    *    * @param dto 包含加解密相关参数信息的实体    * @return 处理结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
*/    @Override    public Result encrypt2Data(ApiEncryptInfoDTO dto) {        String publicKey = PublicKey();        // 若为空,使⽤默认        if (StringUtils.isBlank(publicKey)) {            publicKey = EncryptConstant.PUBLIC_KEY;        }        String data = Data();        //创建sm2 对象        SM2 sm2 = getSM2(null, publicKey);        String dataHex = ptBcd(data, KeyType.PublicKey);        dto.setDataHex(dataHex);        return new Result().ok(dto);    }    /**    * SM2解密    *    * @param dto 包含加解密相关参数信息的实体    * @return 处理结果    */    @Override    public Result decrypt2Data(ApiEncryptInfoDTO dto) {        String privateKey = PrivateKey();        // 若为空,使⽤默认        if (StringUtils.isBlank(privateKey)) {            privateKey = EncryptConstant.PRIVATE_KEY;        }        String dataHex = DataHex();        try {            //创建sm2 对象            SM2 sm2 = getSM2(privateKey, null);            String data = StrUtil.utf8Str(sm2.decryptFromBcd(dataHex, KeyType.PrivateKey));            dto.setData(data);        } catch (Exception e) {            ("SM2解密失败", e);            throw new BaseException("SM2解密失败");        }        return new Result().ok(dto);    }    /**    * SM4加密    *    * @param dto 包含加解密相关参数信息的实体    * @return 处理结果    */    @Override    public Result encrypt4Data(ApiEncryptIn
foDTO dto) {        //指定的密钥        String key = Key();        // 若为空,使⽤默认        if (StringUtils.isBlank(key)) {            key = EncryptConstant.SM4_KEY;        }        String data = Data();        try {            SymmetricCrypto sm4 = SmUtil.Bytes(CharsetUtil.CHARSET_UTF_8));            String dataHex = ptHex(data);            dto.setDataHex(dataHex);        } catch (Exception e) {            ("加密数据异常,异常数据:" + data, e);            throw new BaseException("SM4加密数据异常");        }373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
return new Result().ok(dto);    }    /**    * SM4解密    *    * @param dto 包含加解密相关参数信息的实体    * @return 处理结果    */    @Override    public Result decrypt4Data(ApiEncryptInfoDTO dto) {        //指定的密钥        String key = Key();        // 若为空,使⽤默认        if (StringUtils.isBlank(key)) {            key = EncryptConstant.SM4_KEY;        }        String dataHex = DataHex();        try {            SymmetricCrypto sm4 = SmUtil.Bytes(CharsetUtil.CHARSET_UTF_8));            String data = sm4.decryptStr(dataHex);            dto.setData(data);        } catch (Exception e) {            ("解密数据异常,异常数据:" + dataHex, e);            throw new BaseException("SM4解密数据异常");        }        return new Result().ok(dto);    }    /**    * ⽣成⼀对 C1C2C3 格式的SM2密钥    *   
* @return 处理结果    */    @Override    public Result getSM2Key() {        ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();        //创建sm2 对象        SM2 sm2 = SmUtil.sm2();        byte[] privateKeyByte = PrivateKey());        //这⾥公钥不压缩  公钥的第⼀个字节⽤于表⽰是否压缩  可以不要        byte[] publicKeyByte = ((BCECPublicKey) PublicKey()).getQ().getEncoded(false);        try {            String privateKey = deHexStr(privateKeyByte);            String publicKey = deHexStr(publicKeyByte);            dto.setPublicKey(publicKey);            dto.setPrivateKey(privateKey);        } catch (Exception e) {            ("获取SM2密钥出错", e);            throw new BaseException("获取SM2密钥出错");        }        return new Result().ok(dto);    }    /**    * 获取SM2加密⼯具对象    *    * @param privateKey 加密私钥    * @param publicKey  加密公钥    * @return 处理结果    */    private SM2 getSM2(String privateKey, String publicKey) {        ECPrivateKeyParameters ecPrivateKeyParameters = null;        ECPublicKeyParameters ecPublicKeyParameters = null;        if (StringUtils.isNotBlank(privateKey)) {
102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
储存数据信息的类(这⾥使⽤了lombok的依赖,如果没有的话⾃⼰加上get set)            ecPrivateKeyParameters = Sm2Params(privateKey);        }        if (StringUtils.isNotBlank(pu
blicKey)) {            if (publicKey.length() == 130) {                //这⾥需要去掉开始第⼀个字节 第⼀个字节表⽰标记                publicKey = publicKey.substring(2);            }            String xhex = publicKey.substring(0, 64);            String yhex = publicKey.substring(64, 128);            ecPublicKeyParameters = Sm2Params(xhex, yhex);        }        //创建sm2 对象        SM2 sm2 = new SM2(ecPrivateKeyParameters, ecPublicKeyParameters);        sm2.usePlainEncoding();        sm2.setMode(SM2Engine.Mode.C1C2C3);        return sm2;    }    /**    * 获取⼀个随机的SM4密钥    *    * @return 处理结果    */    @Override    public Result getSM4Key() {        String sm4Key = RandomUtil.randomString(RandomUtil.BASE_CHAR_NUMBER, 16);        ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();        dto.setKey(sm4Key);        return new Result().ok(dto);    }}
167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
⼯具类package com.pt.dto;import lombok.Data;import lombok.EqualsAndHashCode;/** * 数据加密信息DTO  * * @author gbx  * @since 2021-05-27 10:55:32 */@Data @EqualsAndHashCode(callSuper = false)public class ApiEncryptInfoDTO implements Serializable {    private static final long serialVersionUID = 693123123935846450L;    /**    * 加密类型(2:sm2加密,4:sm4加密)    */    private String type;    /**    * ⾮对称加密私钥    */    private String privateKey;    /**    * ⾮对称加密公钥    */    private String publicKey;    /**    * 对称加密
密钥    */    private String key;    /**    * 原始数据    */    private String data;    /**    * 加密后数据    */    private String dataHex;    /**    * ⾮对称加密签名    */    private String sign;}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152import com.pt.dto.ApiEncryptInfoDTO;import com.pt.service.ApiEncryptService;/** * 加解密⼯具类 * * @author gbx 1234567

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。