文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JAVA集成国密SM2

2023-08-16 15:25

关注

国密算法概述:https://blog.csdn.net/qq_38254635/article/details/131801527

SM2椭圆曲线公钥密码算法
为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。

一、pom配置

org.bouncycastlebcprov-jdk15to181.66

二、代码集成

2.1、目录结构

在这里插入图片描述

2.2、源码

KeyConstant.java

package com.secret.sm2;public class KeyConstant {    public static final String PRIVATE_KEY = "pveky"; // 私钥    public static final String PUBLIC_KEY = "pbcky"; // 公钥    public static final String GM_NAME_CURVE = "sm2p256v1";    public static final String ALGORITHM = "SHA1PRNG";}

ModeTypeConstant.java

package com.secret.sm2;import org.bouncycastle.crypto.engines.SM2Engine;public class ModeTypeConstant {    public static final String BASE = "base";    public static final String BC = "bc";    @Deprecated    public static final SM2Engine.Mode BASE_MODE = SM2Engine.Mode.C1C3C2;    @Deprecated    public static final SM2Engine.Mode BC_MODE = SM2Engine.Mode.C1C2C3;    public static ModeTypeEnum getMode(String modeType){        if (ModeTypeEnum.BASE_MODE.getType().equals(modeType)) return ModeTypeEnum.BASE_MODE;        return ModeTypeEnum.BC_MODE;    }}

ModeTypeEnum.java

package com.secret.sm2;import org.bouncycastle.crypto.engines.SM2Engine;public enum ModeTypeEnum {    BASE_MODE(ModeTypeConstant.BASE, SM2Engine.Mode.C1C3C2),    BC_MODE(ModeTypeConstant.BC, SM2Engine.Mode.C1C2C3);    private String type;    private SM2Engine.Mode mode;    ModeTypeEnum(String type, SM2Engine.Mode mode) {        this.type = type;        this.mode = mode;    }    public String getType(){        return type;    }    public SM2Engine.Mode getMode(){        return mode;    }}

SecretCommon.java

package com.secret.sm2;import org.bouncycastle.asn1.gm.GMNamedCurves;import org.bouncycastle.asn1.x9.X9ECParameters;import org.bouncycastle.crypto.AsymmetricCipherKeyPair;import org.bouncycastle.crypto.InvalidCipherTextException;import org.bouncycastle.crypto.engines.SM2Engine;import org.bouncycastle.crypto.generators.ECKeyPairGenerator;import org.bouncycastle.crypto.params.ECDomainParameters;import org.bouncycastle.crypto.params.ECKeyGenerationParameters;import org.bouncycastle.crypto.params.ECPrivateKeyParameters;import org.bouncycastle.crypto.params.ECPublicKeyParameters;import org.bouncycastle.crypto.params.ParametersWithRandom;import org.bouncycastle.math.ec.ECPoint;import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;import org.bouncycastle.util.encoders.Hex;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.math.BigInteger;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import java.util.HashMap;import java.util.Map;public class SecretCommon {    //获取椭圆曲线    public static synchronized ECDomainParameters getECDomainParameters() {        X9ECParameters sm2ECParameters = GMNamedCurves.getByName(KeyConstant.GM_NAME_CURVE);        return new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());    }        public static Map createKeyPair() throws NoSuchAlgorithmException {        ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();        keyPairGenerator.init(new ECKeyGenerationParameters(getECDomainParameters(), SecureRandom.getInstance(KeyConstant.ALGORITHM)));        AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();        Map map = new HashMap<>();        BigInteger bigInteger = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();        map.put(KeyConstant.PRIVATE_KEY, ByteUtils.toHexString(bigInteger.toByteArray()));        // 把公钥放入map中,默认压缩公钥        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥,04的时候,可以去掉前面的04        ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();        map.put(KeyConstant.PUBLIC_KEY, ByteUtils.toHexString(ecPoint.getEncoded(false)));        return map;    }        public static String encrypt(String plainText, String publicKey, ModeTypeEnum modeType) throws IOException, InvalidCipherTextException {        return encrypt(plainText.getBytes(), publicKey, modeType.getMode());    }        public static String encrypt(byte[] plainByte, String publicKey, SM2Engine.Mode mode) throws IOException, InvalidCipherTextException {        ECDomainParameters domainParameters = getECDomainParameters();        //提取公钥点        ECPoint ecPoint = domainParameters.getCurve().decodePoint(ByteUtils.fromHexString(publicKey));        // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04        ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(ecPoint, domainParameters);        SM2Engine sm2Engine = new SM2Engine(mode);        sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));        return ByteUtils.toHexString(sm2Engine.processBlock(plainByte, 0, plainByte.length));    }        public static String decrypt(String cipherText, String privateKey, ModeTypeEnum modeType) throws InvalidCipherTextException, UnsupportedEncodingException {        return decrypt(Hex.decode(cipherText), privateKey, modeType.getMode());    }        public static String decrypt(byte[] cipherDataByte, String privateKeyHex, SM2Engine.Mode mode) throws InvalidCipherTextException, UnsupportedEncodingException {        BigInteger bigInteger = new BigInteger(privateKeyHex, 16);        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(bigInteger, getECDomainParameters());        SM2Engine sm2Engine = new SM2Engine(mode);        sm2Engine.init(false, privateKeyParameters);        return new String(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length), "utf-8");    }}

Utils.java

package com.secret.sm2;import org.bouncycastle.crypto.InvalidCipherTextException;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.security.NoSuchAlgorithmException;import java.util.Map;public class Utils {        public static Map createKeyPair() throws NoSuchAlgorithmException {        return SecretCommon.createKeyPair();    }        public static String encrypt(String plainText, String publicKey) throws IOException, InvalidCipherTextException {        return encrypt(plainText, publicKey, ModeTypeConstant.BASE);    }        public static String encrypt(String plainText, String publicKey, String modeType) throws IOException, InvalidCipherTextException {        return SecretCommon.encrypt(plainText, publicKey, ModeTypeConstant.getMode(modeType));    }        public static String decrypt(String cipherText, String privateKey) throws InvalidCipherTextException, UnsupportedEncodingException {        return decrypt(cipherText, privateKey, ModeTypeConstant.BASE);    }        public static String decrypt(String cipherText, String privateKey, String modeType) throws InvalidCipherTextException, UnsupportedEncodingException {        return SecretCommon.decrypt(cipherText, privateKey, ModeTypeConstant.getMode(modeType));    }}

测试类:Test.java

package com.secret.sm2;import java.util.Map;public class Test {    public static void main(String[] args) throws Exception {        Map createKeyPair = Utils.createKeyPair();        System.out.println("秘钥对:" + createKeyPair);        String privateKey = createKeyPair.get(KeyConstant.PRIVATE_KEY);        String publicKey = createKeyPair.get(KeyConstant.PUBLIC_KEY);        String text = "I believe you can do anything";        String encrypt = Utils.encrypt(text, publicKey);        System.out.println("加密后密文:" + encrypt);        String decrypt = Utils.decrypt(encrypt, privateKey);        System.out.println("解密后明文:" + decrypt);    }}

2.3、测试

测试结果如图:
在这里插入图片描述
使用方法参考测试类即可。

三、相关链接

国密算法概述:https://blog.csdn.net/qq_38254635/article/details/131801527

JAVA集成国密SM3:https://blog.csdn.net/qq_38254635/article/details/131810696

JAVA集成国密SM4:https://blog.csdn.net/qq_38254635/article/details/131810715

来源地址:https://blog.csdn.net/qq_38254635/article/details/131810661

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯