失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 国密算法SM2加密解密

国密算法SM2加密解密

时间:2020-01-15 16:37:39

相关推荐

国密算法SM2加密解密

一、依赖包

<!-- hutool的 SM2 加密--><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.68</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.2</version></dependency>

二、工具类

首先创建一个用于存储加密解密内容的实体:

package com.bw.note.util.SM2.SP;import lombok.Data;import lombok.EqualsAndHashCode;import java.io.Serializable;@Data@EqualsAndHashCode(callSuper = false)public class ApiEncryptInfoDTO implements Serializable {private static final long serialVersionUID = 255205006827117733L;/*** 加密类型(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;}

接着是具体的加密解密过程工具类:

package com.bw.note.util.SM2.SP;import cn.hutool.core.util.CharsetUtil;import cn.hutool.core.util.HexUtil;import cn.hutool.core.util.RandomUtil;import cn.hutool.core.util.StrUtil;import cn.hutool.crypto.BCUtil;import cn.hutool.crypto.SmUtil;import cn.hutool.crypto.asymmetric.KeyType;import cn.hutool.crypto.asymmetric.SM2;import cn.hutool.crypto.symmetric.SymmetricCrypto;import lombok.extern.slf4j.Slf4j;import mons.lang.StringUtils;import org.bouncycastle.crypto.engines.SM2Engine;import org.bouncycastle.crypto.params.ECPrivateKeyParameters;import org.bouncycastle.crypto.params.ECPublicKeyParameters;import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;@Slf4jpublic class SM2Utils {/*** SM2加密** @param dto 包含加解密相关参数信息的实体* @return 处理结果*/public static ApiEncryptInfoDTO encrypt2Data(ApiEncryptInfoDTO dto){String publicKey = dto.getPublicKey();// 若为空,使用默认if (StringUtils.isBlank(publicKey)) {publicKey = "04db9629dd33ba568e9507add5df6587a0998361a03d3321948b448c653c2c1b7056434884ab6f3d1c529501f166a336e86f045cea10dffe58aa82ea13d7253763";}String data = dto.getData();//创建sm2 对象SM2 sm2 = getSM2(null, publicKey);String dataHex = sm2.encryptBcd(data, KeyType.PublicKey);dto.setDataHex(dataHex);return dto;}/*** SM2解密* @param dto 包含加解密相关参数信息的实体* @return 处理结果*/public static ApiEncryptInfoDTO decrypt2Data(ApiEncryptInfoDTO dto){String privateKey = dto.getPrivateKey();// 若为空,使用默认if (StringUtils.isBlank(privateKey)) {privateKey = "1ebf8b341c695ee456fd1a41b82645724bc25d79935437d30e7e4b0a554baa5e";}String dataHex = dto.getDataHex();try {//创建sm2 对象SM2 sm2 = getSM2(privateKey, null);String data = StrUtil.utf8Str(sm2.decryptFromBcd(dataHex, KeyType.PrivateKey));dto.setData(data);} catch (Exception e) {log.error("SM2解密失败", e);}return dto;}/*** SM4加密** @param dto 包含加解密相关参数信息的实体* @return 处理结果*/public static ApiEncryptInfoDTO encrypt4Data(ApiEncryptInfoDTO dto) {//指定的密钥String key = dto.getKey();// 若为空,使用默认if (StringUtils.isBlank(key)) {key = "zps9yv341b3s90c2";}String data = dto.getData();try {SymmetricCrypto sm4 = SmUtil.sm4(key.getBytes(CharsetUtil.CHARSET_UTF_8));String dataHex = sm4.encryptHex(data);dto.setDataHex(dataHex);} catch (Exception e) {log.error("加密数据异常,异常数据:" + data, e);}return dto;}/*** SM4解密** @param dto 包含加解密相关参数信息的实体* @return 处理结果*/public static ApiEncryptInfoDTO decrypt4Data(ApiEncryptInfoDTO dto) {//指定的密钥String key = dto.getKey();// 若为空,使用默认if (StringUtils.isBlank(key)) {key = "zps9yv341b3s90c2";}String dataHex = dto.getDataHex();try {SymmetricCrypto sm4 = SmUtil.sm4(key.getBytes(CharsetUtil.CHARSET_UTF_8));String data = sm4.decryptStr(dataHex);dto.setData(data);} catch (Exception e) {log.error("解密数据异常,异常数据:" + dataHex, e);}return dto;}/*** 获取SM2加密工具对象** @param privateKey 加密私钥* @param publicKey 加密公钥* @return 处理结果*/private static SM2 getSM2(String privateKey, String publicKey) {ECPrivateKeyParameters ecPrivateKeyParameters = null;ECPublicKeyParameters ecPublicKeyParameters = null;if (StringUtils.isNotBlank(privateKey)) {ecPrivateKeyParameters = BCUtil.toSm2Params(privateKey);}if (StringUtils.isNotBlank(publicKey)) {if (publicKey.length() == 130) {//这里需要去掉开始第一个字节 第一个字节表示标记publicKey = publicKey.substring(2);}String xhex = publicKey.substring(0, 64);String yhex = publicKey.substring(64, 128);ecPublicKeyParameters = BCUtil.toSm2Params(xhex, yhex);}//创建sm2 对象SM2 sm2 = new SM2(ecPrivateKeyParameters, ecPublicKeyParameters);sm2.usePlainEncoding();sm2.setMode(SM2Engine.Mode.C1C2C3);return sm2;}/*** 生成一对 C1C2C3 格式的SM2密钥** @return 处理结果*/public static ApiEncryptInfoDTO getSM2Key() {ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();//创建sm2 对象SM2 sm2 = SmUtil.sm2();byte[] privateKeyByte = BCUtil.encodeECPrivateKey(sm2.getPrivateKey());//这里公钥不压缩 公钥的第一个字节用于表示是否压缩 可以不要byte[] publicKeyByte = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);try {String privateKey = HexUtil.encodeHexStr(privateKeyByte);String publicKey = HexUtil.encodeHexStr(publicKeyByte);dto.setPublicKey(publicKey);dto.setPrivateKey(privateKey);} catch (Exception e) {log.error("获取SM2密钥出错", e);}return dto;}/*** 获取一个随机的SM4密钥** @return 处理结果*/public static ApiEncryptInfoDTO getSM4Key() {String sm4Key = RandomUtil.randomString(RandomUtil.BASE_CHAR_NUMBER, 16);ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();dto.setKey(sm4Key);return dto;}}

最后是测试工具类

package com.bw.note.util.SM2.SP;import org.junit.Test;public class test {/*** 测试SM2加密*/@Testpublic void test01(){ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();dto.setData("123456");dto = SM2Utils.encrypt2Data(dto);System.out.println(dto.getDataHex());}/*** 测试SM2解密*/@Testpublic void test02(){ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();dto.setDataHex("046A331A8227AD1CCC7E33ECEAEF7CF1CD7D3F3EEE2218E4A0AD1BE08ED5E65F0DB6811656FAE4CD1A16D8E79DE66FCF80A08158CD7E34523E76975789B18AE2C9FF9012BD47E0F84BC778538D6A6C17304A83F2F57014EC0C257987D8DA93403D53F193234DB8");dto = SM2Utils.decrypt2Data(dto);System.out.println(dto.getData());}/*** 生成一对 C1C2C3 格式的SM2密钥*/@Testpublic void test03(){ApiEncryptInfoDTO dto = SM2Utils.getSM2Key();System.out.println(dto.getPublicKey());System.out.println(dto.getPrivateKey());}/*** 获取一个随机的SM4密钥*/@Testpublic void test04(){ApiEncryptInfoDTO dto = SM2Utils.getSM4Key();System.out.println(dto.getKey());}/*** 测试SM4加密*/@Testpublic void test05(){ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();dto.setData("123456");dto = SM2Utils.encrypt4Data(dto);System.out.println(dto.getDataHex());}/*** 测试SM4解密*/@Testpublic void test06(){ApiEncryptInfoDTO dto = new ApiEncryptInfoDTO();dto.setDataHex("0c878839ddba1631931ca9e7f9c981eb");dto = SM2Utils.decrypt4Data(dto);System.out.println(dto.getData());}}

如果觉得《国密算法SM2加密解密》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。