SM2——适用于前后端(java+vue)公用的SM2国密加解密传输

目录

    • 一、SM2国密加解密算法
      • 1.1、pom文件引入依赖包
      • 1.2、SM2加解密工具类
      • 1.3、测试类

一、SM2国密加解密算法

1.1、pom文件引入依赖包

 <dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcprov-jdk18on</artifactId>
     <version>1.72</version>
 </dependency>

1.2、SM2加解密工具类

  • SM2加解密工具类

    package com.xz.utils;
    import org.bouncycastle.asn1.gm.GMNamedCurves;
    import org.bouncycastle.asn1.x9.X9ECParameters;
    import org.bouncycastle.crypto.engines.SM2Engine;
    import org.bouncycastle.crypto.params.*;
    import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
    import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.math.ec.ECPoint;
    import org.bouncycastle.util.encoders.Hex;
    
    import java.math.BigInteger;
    import java.security.*;
    import java.security.spec.ECGenParameterSpec;
    import java.util.HashMap;
    import java.util.Map;
    
    
    /**
     * 适用于前后端公用的SM2秘钥生成、加解密工具类
     */
    public class SimpSM2Util {
        /**
         * 公钥常量
         */
        public static final String KEY_PUBLIC_KEY = "publicKey";
        /**
         * 私钥返回值常量
         */
        public static final String KEY_PRIVATE_KEY = "privateKey";
    
        /**
         * SM2加密算法
         * @param publicKey     公钥
         * @param data          明文数据
         * @return
         */
        public static String encrypt(String publicKey, String data) {
            // 获取一条SM2曲线参数
            X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
            // 构造ECC算法参数,曲线方程、椭圆曲线G点、大整数N
            ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
            //提取公钥点
            ECPoint pukPoint = sm2ECParameters.getCurve().decodePoint(Hex.decode(publicKey));
            // 公钥前面的02或者03表示是压缩公钥,04表示未压缩公钥, 04的时候,可以去掉前面的04
            ECPublicKeyParameters publicKeyParameters = new ECPublicKeyParameters(pukPoint, domainParameters);
    
            SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
            // 设置sm2为加密模式
            sm2Engine.init(true, new ParametersWithRandom(publicKeyParameters, new SecureRandom()));
    
            byte[] arrayOfBytes = null;
            try {
                byte[] in = data.getBytes();
                arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
            } catch (Exception e) {
                System.out.println("SM2加密时出现异常:"+e.getMessage());
            }
            return Hex.toHexString(arrayOfBytes);
    
        }
    
        /**
         * SM2解密算法
         * @param privateKey        私钥
         * @param cipherData        密文数据
         * @return
         */
        public static String decrypt(String privateKey, String cipherData) {
            // 使用BC库加解密时密文以04开头,传入的密文前面没有04则补上
            if (!cipherData.startsWith("04")){
                cipherData = "04" + cipherData;
            }
            byte[] cipherDataByte = Hex.decode(cipherData);
            BigInteger privateKeyD = new BigInteger(privateKey, 16);
            //获取一条SM2曲线参数
            X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
            //构造domain参数
            ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
            ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
    
            SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
            // 设置sm2为解密模式
            sm2Engine.init(false, privateKeyParameters);
    
            String result = "";
            try {
                byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
                return new String(arrayOfBytes);
            } catch (Exception e) {
                System.out.println("SM2解密时出现异常:"+e.getMessage());
            }
            return result;
        }
     
        /**
         * 生成密钥
         */
        public static Map<String, String> createKey() throws Exception{
            ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
            // 获取一个椭圆曲线类型的密钥对生成器
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
            // 使用SM2参数初始化生成器
            kpg.initialize(sm2Spec);
            // 获取密钥对
            KeyPair keyPair = kpg.generateKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            BCECPublicKey p=(BCECPublicKey)publicKey;
            System.out.println("publicKey:"+Hex.toHexString(p.getQ().getEncoded(false)));
            PrivateKey privateKey = keyPair.getPrivate();
            BCECPrivateKey s=(BCECPrivateKey)privateKey;
            System.out.println("privateKey:"+Hex.toHexString(s.getD().toByteArray()));
            Map<String, String> result = new HashMap<>();
            result.put(KEY_PUBLIC_KEY, Hex.toHexString(p.getQ().getEncoded(false)));
            result.put(KEY_PRIVATE_KEY, Hex.toHexString(s.getD().toByteArray()));
            return result;
        }
    
    }
    

1.3、测试类

  • 测试类

    public static void main(String[] args) throws Exception {
          Map<String, String> key = createKey();
           String publicKey = key.get(KEY_PUBLIC_KEY);
           System.out.println("公钥:"+publicKey);
           String privateKey = key.get(KEY_PRIVATE_KEY);
           System.out.println("私钥:"+privateKey);
    
           String str="hello java123456";
           System.out.println("加密前结果:"+str);
           String encrypt = encrypt(publicKey, str);
           System.out.println("加密后结果:"+encrypt);
           String decrypt = decrypt(privateKey, encrypt);
           System.out.println("解密后结果:"+decrypt);
    }
    
  • 测试结果,如下图所示:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/286250.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JMeter使用

目录 启动JMeter 创建线程组 设置线程参数 设置http请求参数 ​编辑 创建查看结果树(显示成功/失败多少以及返回结果等信息) 创建聚合报告(显示响应时间、吞吐量、异常数等信息) 点击上方的执行按钮即可开始压力测试 结果树显示 聚合报告结果显示 启动JMeter 在JMete…

产品经理学习-从0-1搭建策略产品

从0-1搭建策略产品 目录&#xff1a; 回顾策略产品 如何从0-1搭建策略产品 回顾策略产品 之前也了解过从产品实施的角度来看&#xff0c;策略就是针对问题的解决方案&#xff0c;在互联网时代更集中体现在2个维度&#xff1a;业务场景和数据应用 如何从0-1搭建策略产品 我们…

HTML5+CSS3④——选择器、复合选择器

目录 选择器 标签选择器 类选择器 id选择器 通配符选择器 复合选择器 后代选择器 子代选择器 并集选择器 交集选择器 选择器 标签选择器 类选择器 id选择器 通配符选择器 复合选择器 后代选择器 子代选择器 并集选择器 交集选择器

一文读懂OTA【赠书活动|第12期《一书读懂物联网:基础知识+运行机制+工程实现》】

2020年&#xff0c;特斯拉发布过一次OTA更新&#xff0c;车主可以通过这次系统更新获得座椅加热功能。当时&#xff0c;这则新闻震惊了车圈和所有车主&#xff0c;彼时的大家还没有把汽车当作可以“升级”的智能设备。 如今3年过去了&#xff0c;车主对各家车企的OTA升级早已见…

easyrecovery 2024最新免费密钥分享 实用数据恢复软件分享

在日常使用电脑时&#xff0c;我们经常会遇到误删文件的情况&#xff0c;若文件还未被彻底删除&#xff0c;我们还可以通过电脑中的回收站将其恢复&#xff0c;但若是回收站都被清空的话&#xff0c;想要恢复文件就变得比较困难了&#xff0c;而EasyRecovery可以很好的帮助我们…

关键字:new关键字

在 Java 中&#xff0c;new关键字用于创建对象实例。它是对象创建的语法糖&#xff0c;用于分配内存空间并调用构造函数来初始化对象。 以下是new关键字的基本语法&#xff1a; 在上述语法中&#xff0c;ObjectType是要创建对象的类名&#xff0c;objectName是对象的引用变量…

Stable Diffusion API入门:简明教程

Stable Diffusion 是一个先进的深度学习模型&#xff0c;用于创造和修改图像。这个模型能够基于文本描述来生成图像&#xff0c;让机器理解和实现用户的创意。使用这项技术的关键在于掌握其 API&#xff0c;通过编程来操控图像生成的过程。 在探索 Stable Diffusion API 的世界…

CISSP 第1章:实现安全治理的原则和策略

作者&#xff1a;nothinghappend 链接&#xff1a;https://zhuanlan.zhihu.com/p/669881930 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 CIA CIA 三性&#xff1a; 机密性&#xff1a;和数据泄露有关。完整性…

工业交换机进行高低温检测的原因是什么?

工业交换机进行高低温检测的原因有以下几点&#xff1a; 1. 确保设备正常工作&#xff1a;工业交换机在工作过程中会产生一定的热量&#xff0c;如果环境温度过高&#xff0c;可能会导致设备过热&#xff0c;影响交换机的性能和寿命。通过高温检测&#xff0c;可以及时采取措施…

基于蝴蝶算法优化的Elman神经网络数据预测 - 附代码

基于蝴蝶算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于蝴蝶算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于蝴蝶优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针…

SpringBoot知识

1、Spring和SpringBoot对比 2、版本调整 &#xff08;1&#xff09;先排除是否是JDK与SpringBoot的版本不一致导致的&#xff1a;如JDK1.8和SpringBoot3.1.5冲突&#xff1b; &#xff08;2&#xff09;调整编译版本 &#xff08;3&#xff09;调整maven的jdk &#xff08;4&…

基于蜻蜓算法优化的Elman神经网络数据预测 - 附代码

基于蜻蜓算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于蜻蜓算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于蜻蜓优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针…

【解决】电脑上的WIFI图标不见了咋整?

相信不少同学都遇到过这种情况&#xff1a;电脑上的wifi图标莫名不见了&#xff0c;甚至有时候还是在使用的中途突然断网消失的。 遇到这种情况一般有两种解决方案&#xff1a; 1. 在开机状态下长按电源键30秒以上 这种办法应该是给主板放电&#xff0c;一般应用在wifi6上面。…

我的机器学习起步如何Getting Started

学习技巧和原则 先通过经典书籍进行科普知名机器学习网站根据书籍或网站的目录&#xff0c;先泛读、再选择有兴趣的部分重点精读、后至于反复读知行合一 起步Getting Started 周志华版《机器学习》&#xff0c;又名西瓜书 可以作为科普书籍&#xff0c;需要主动略过对于理论…

无监督关键词提取算法:TF-IDF、TextRank、RAKE、YAKE、 keyBERT

TF-IDF TF-IDF是一种经典的基于统计的方法&#xff0c;TF(Term frequency)是指一个单词在一个文档中出现的次数&#xff0c;通常一个单词在一个文档中出现的次数越多说明该词越重要。IDF(Inverse document frequency)是所有文档数比上出现某单词的个数&#xff0c;通常一个单词…

IEEE 802.15.4和ZigBee基础

该文章不知道从哪里抄的&#xff0c;忘记出处了&#xff0c;放在电脑中很久了。里面略有改动。若有侵权&#xff0c;请告诉我删除。IEEE 802.15.4网络是指在一个POS&#xff08;10米左右范围&#xff09;内使用相同的无线信道&#xff0c;并通过IEEE 802.15.4标准相互通信的一组…

【MySQL】orderby/groupby出现Using filesort根因分析及优化

序 在日常的数据库运维中&#xff0c;我们可能会遇到一些看似难以理解的现象。比如两个SQL查询语句&#xff0c;仅仅在ORDER BY子句上略有不同&#xff0c;却造成了性能的天壤之别——一个飞速完成&#xff0c;一个则让数据库崩溃。今天就让我们围绕这个问题&#xff0c;深入剖…

我这个小白坚持写作一整年,赚了多少?

今天是 2023 年的最后一天&#xff0c;和大家一起来一个年终复盘&#xff0c;主题就是&#xff1a;2023年&#xff0c;我到底赚了多少&#xff1f; 今年除了工作之外&#xff0c;我的重点都放在了写文章上。 截止到今天&#xff0c;已经在公众号上发布了 100 篇原创文章&…

selenium3自动化测试(这一篇就够了)——自学篇

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

瑞吉外卖项目详细总结

文章目录 瑞吉外卖1.技术栈2.项目文件架构3.业务功能模块&#xff08;例子&#xff09;3.1管理员登录接口层(Controller)3.2管理员登录实现层(ServiceImpl)3.3管理员登录服务层&#xff08;Service&#xff09;3.4管理员登录Mapper层 4.公共模块4.1 BaseContext&#xff08;保存…