首页 > 其他分享 >国密SM2加解密Demo

国密SM2加解密Demo

时间:2023-02-27 10:15:31浏览次数:52  
标签:String Demo 加解密 sm2 param SM2 publicKey 国密 BCUtil

国密SM2加解密Demo

1、pom.xml

<!-- 国密 START-->
<!--        <dependency>-->
<!--            <groupId>org.bouncycastle</groupId>-->
<!--            <artifactId>bcprov-jdk15to18</artifactId>-->
<!--            <version>1.71</version>-->
<!--        </dependency>-->
<!-- 国密 END -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.5.8</version>
</dependency>

2、代码:

import cn.hutool.core.util.HexUtil;
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 lombok.extern.slf4j.Slf4j;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;

import java.security.PrivateKey;
import java.security.PublicKey;

/**
 * 国密.
 *
 * @author lizhm
 */
@Slf4j
public class Sm2Util {

    public static String PRIVATE_KEY = "";

    public static String PUBLIC_KEY = "";

    private static int PUBLIC_LENGTH = 130;

    /**
     * 生成公钥、私钥.
     *
     * @author lizhm
     * @date 2023/2/21 16:37
     * @history <author>  <time>  <version>  <desc>
     */
    private static void genKeyPair() {
        SM2 sm2 = SmUtil.sm2();
        // 私钥:切记不要泄漏,真的泄露了就重新生成一下
        byte[] privateKey = BCUtil.encodeECPrivateKey(sm2.getPrivateKey());
        //这里默认公钥压缩  公钥的第一个字节用于表示是否压缩 02或者03表示是压缩公钥,04表示未压缩公钥
        byte[] publicKey = BCUtil.encodeECPublicKey(sm2.getPublicKey());
        //这里得到未压缩的公钥  byte[] publicKey = ((BCECPublicKey) sm2.getPublicKey()).getQ().getEncoded(false);
        PRIVATE_KEY = HexUtil.encodeHexStr(privateKey);
        PUBLIC_KEY = HexUtil.encodeHexStr(publicKey);
    }

    /**
     * SM2加密算法.
     *
     * @param data 加密前的明文
     * @param publicKey 公钥
     * @return String 加密后的密文
     * @author lizhm
     * @history <author>  <time>  <version>  <desc>
     */
    public static String encrypt(String publicKey, String data) {
        ECPublicKeyParameters ecPublicKeyParameters = null;
        //这里需要根据公钥的长度进行加工
        if (publicKey.length() == PUBLIC_LENGTH) {
            //这里需要去掉开始第一个字节 第一个字节表示标记
            publicKey = publicKey.substring(2);
            String xhex = publicKey.substring(0, 64);
            String yhex = publicKey.substring(64, 128);
            ecPublicKeyParameters = BCUtil.toSm2Params(xhex, yhex);
        } else {
            PublicKey p = BCUtil.decodeECPoint(publicKey, SmUtil.SM2_CURVE_NAME);
            ecPublicKeyParameters = BCUtil.toParams(p);
        }
        //创建sm2 对象
        SM2 sm2 = new SM2(null, ecPublicKeyParameters);
        // 公钥加密
        return sm2.encryptBcd(data, KeyType.PublicKey);
    }

    /**
     * SM2加密算法.
     *
     * @param publicKey 公钥
     * @param text 明文数据
     * @return String
     * @author lizhm
     * @history <author>  <time>  <version>  <desc>
     */
    public static String encrypt(PublicKey publicKey, String text) {
        ECPublicKeyParameters ecPublicKeyParameters = BCUtil.toParams(publicKey);
        //创建sm2 对象
        SM2 sm2 = new SM2(null, ecPublicKeyParameters);
        // 公钥加密
        return sm2.encryptBcd(text, KeyType.PublicKey);
    }

    /**
     * SM2解密算法.
     *
     * @param cipherData 加密密文
     * @param privateKey 私秘钥
     * @return String 解密后的明文字符串
     * @author lizhm
     * @history <author>  <time>  <version>  <desc>
     */
    public static String decrypt(String privateKey, String cipherData) {
        if (StrUtil.isBlank(cipherData)) {
            throw new RuntimeException("解密串为空,解密失败");
        }
        ECPrivateKeyParameters ecPrivateKeyParameters = BCUtil.toSm2Params(privateKey);
        //创建sm2 对象
        SM2 sm2 = new SM2(ecPrivateKeyParameters, null);
        // 私钥解密
        return StrUtil.utf8Str(sm2.decryptFromBcd(cipherData, KeyType.PrivateKey));
    }

    /**
     * SM2解密算法.
     *
     * @param privateKey 私钥
     * @param cipherData 密文数据
     * @return String
     * @author lizhm
     * @history <author>  <time>  <version>  <desc>
     */
    public static String decrypt(PrivateKey privateKey, String cipherData) {
        ECPrivateKeyParameters ecPrivateKeyParameters = BCUtil.toParams(privateKey);
        //创建sm2 对象
        SM2 sm2 = new SM2(ecPrivateKeyParameters, null);
        // 私钥解密
        return StrUtil.utf8Str(sm2.decryptFromBcd(cipherData, KeyType.PrivateKey));
    }

    /**
     * 私钥签名.
     *
     * @param privateKey 私钥
     * @param content 待签名内容
     * @return String
     * @author lizhm
     * @history <author>  <time>  <version>  <desc>
     */
    public static String sign(String privateKey, String content) {
        ECPrivateKeyParameters ecPrivateKeyParameters = BCUtil.toSm2Params(privateKey);
        //创建sm2 对象
        SM2 sm2 = new SM2(ecPrivateKeyParameters, null);
        return sm2.signHex(HexUtil.encodeHexStr(content));
    }

    /**
     * 验证签名.
     *
     * @param publicKey 公钥
     * @param content 待签名内容
     * @param sign 签名值
     * @return boolean
     * @author lizhm
     * @history <author>  <time>  <version>  <desc>
     */
    public static boolean verify(String publicKey, String content, String sign) {
        ECPublicKeyParameters ecPublicKeyParameters;
        //这里需要根据公钥的长度进行加工
        if (publicKey.length() == PUBLIC_LENGTH) {
            //这里需要去掉开始第一个字节 第一个字节表示标记
            publicKey = publicKey.substring(2);
            String xhex = publicKey.substring(0, 64);
            String yhex = publicKey.substring(64, 128);
            ecPublicKeyParameters = BCUtil.toSm2Params(xhex, yhex);
        } else {
            PublicKey p = BCUtil.decodeECPoint(publicKey, SmUtil.SM2_CURVE_NAME);
            ecPublicKeyParameters = BCUtil.toParams(p);
        }
        //创建sm2 对象
        SM2 sm2 = new SM2(null, ecPublicKeyParameters);
        return sm2.verifyHex(HexUtil.encodeHexStr(content), sign);
    }
}

 

标签:String,Demo,加解密,sm2,param,SM2,publicKey,国密,BCUtil
From: https://www.cnblogs.com/lizm166/p/17158678.html

相关文章

  • 列式数据库clickhouse的JDBC连接Demo
    列式数据库clickhouse的JDBC连接Demo1、JDBC代码:packagecom.fs.idc.qh.util;importru.yandex.clickhouse.ClickHouseConnection;importru.yandex.clickhouse.Clic......
  • 【MAUI】resource mipmap/appicon (aka com.companyname.mauiblazordemoapp:mipmap/ap
    问题出现描述我在向Resource文件夹下的Appicon和Splash里面分别添加了一个svg图标。随后我更改项目csproj文件里面的图标,随后启动项目出现错误。解决问题首先我删除了b......
  • MySQL_demo_50道习题
    title:MySQL_demo_50道习题author:杨晓东permalink:MySQL_demodate:2021-10-0211:27:04categories:-投篮tags:-demo表名和字段–1.学生表Student(s_id,s......
  • java的一个小demo
    publicstaticvoidmain(String[]args){intnum=0;num=num++;System.out.println(num);//0num=++num;Sys......
  • PHP DateTime 对象和 Date 函数的 Demo
    DateTime对象<?php//设置时间时区date_default_timezone_set('PRC');$dateFormat="Y-m-d";$dateTimeFormat="Y-m-dH:i:s";//获取当前时间$date=newDateTi......
  • ar小Demo(aframe.js)
    官网:https://aframe.io/中文网:https://www.techbrood.com/aframe/guides?p=building-a-basic-scene虚拟现实https://mp.weixin.qq.com/s/6ddpdknOHAKO9ORUPIqnAg......
  • Kill Demodogs
    题意大意是求思路n项平方和求法:1+4+9+16+....+\(n^2\)=1*1+2*2+3*3+...+n*n=(1+2+3+...+n)+(1*2+2*3+...+(n-......
  • 基于matlab的AES加解密算法仿真
    1.算法描述AES算法在对明文加密的时候,并不是把整个明文一股脑的加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。这些明文块经过AES加密器复......
  • 基于matlab的AES加解密算法仿真
    1.算法描述        AES算法在对明文加密的时候,并不是把整个明文一股脑的加密成一整段密文,而是把明文拆分成一个个独立的明文块,每一个明文块长度128bit。这些明文......
  • BackTrader 简单BTC的SMA15回测DEMO
    importtimeimportrequestsimportjsonimportcsvfromrequests.packages.urllib3importdisable_warningsdisable_warnings()#BTC历史价格获取if__name__=='......