国密算法(SM2)java语言的实现:利用bcprov库来实现SM2算法,非对称算法

2023-05-16

SM2算法简介

随着密码技术和计算机技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。

  • SM2是非对称加密算法;
  • SM2是基于椭圆曲线密码的公钥密码算法标准;
  • SM2是国密算法,用于替换RSA/DH/ECDSA/ECDH等国际算法;
  • SM2算法由国家密码管理局于2010年12月17日发布;
  • SM2推荐了一条256位的曲线作为标准曲线;
  • SM2算法在很多方面都优于RSA算法;
  • SM2性能更优更安全:密码复杂度高、处理速度快、机器性能消耗更小;

SM2标准:

SM2标准包括总则,数字签名算法,密钥交换协议,公钥加密算法四个部分。

  • SM2算法主要考虑素域Fp和F2m上的椭圆曲线,分别介绍了这两类域的表示,运算,以及域上的椭圆曲线的点的表示,运算和多倍点计算算法。然后介绍了编程语言中的数据转换,包括整数和字节串,字节串和比特串,域元素和比特串,域元素和整数,点和字节串之间的数据转换规则。详细说明了有限域上椭圆曲线的参数生成以及验证,椭圆曲线的参数包括有限域的选取、椭圆曲线方程参数、椭圆曲线群基点的选取等,并给出了选取的标准以便于验证。最后给椭圆曲线上密钥对的生成以及公钥的验证,用户的密钥对为(s,sP),其中s为用户的私钥,sP为用户的公钥,由于离散对数问题从sP难以得到s,并针对素域和二元扩域给出了密钥对生成细节和验证方式。总则中的知识也适用于SM9算法。
  • 在总则的基础上给出了数字签名算法(包括数字签名生成算法和验证算法),密钥交换协议以及公钥加密算法(包括加密算法和解密算法),并在每个部分给出了算法描述,算法流程和相关示例。
  • 数字签名算法、密钥交换协议以及公钥加密算法都使用了国家密管理局批准的SM3密码杂凑算法和随机数发生器。数字签名算法、密钥交换协议以及公钥加密算法根据总则来选取有限域和椭圆曲线,并生成密钥对。

使用bcprov库来实现SM2算法的封装:

用maven编译,pom.xml文件:

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15to18</artifactId>
            <version>1.64</version>
        </dependency>

SM2算法工具类Sm2CryptTools
Sm2CryptTools.java:

package com.abc.smutilstest;


import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.bouncycastle.util.encoders.Hex;

import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.ECGenParameterSpec;

/**
 * SM2算法工具类
 */
public class Sm2CryptTools {
    private final KeyPair mKeyPair;
    public Sm2CryptTools() throws Exception {
        mKeyPair = initKey();
    }

    /**
     * 创建密钥对
     * @return 密钥对KeyPair
     * @throws Exception
     */
    public KeyPair initKey()  throws Exception{
        try {
            ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
            // 获取一个椭圆曲线类型的密钥对生成器
            final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
            // 使用SM2参数初始化生成器
            kpg.initialize(sm2Spec);
            // 获取密钥对
            KeyPair keyPair = kpg.generateKeyPair();
            return keyPair;
        }catch (Exception e) {
            throw new Exception(e);
        }
    }

    /**
     * sm2加密算法
     * @param pubkey:公钥
     * @param plainData:要加密的字符串
     * @return:加密结果
     */
    public String encrypt(PublicKey pubkey,String plainData) {
        try {
            SM2Engine sm2Engine = MySm2Engine.createMySm2Engine(pubkey,null,MySm2Engine.Type_Encode);
            //encrypt data
            byte[] bytes = null;
            try {
                byte[] in = plainData.getBytes(StandardCharsets.UTF_8);
                bytes = sm2Engine.processBlock(in,0, in.length);
            }
            catch (Exception e) {
                System.out.println("SM2加密失败:");
            }
            return Hex.toHexString(bytes);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * sm2解密算法
     * @param priKey:私钥
     * @param cipherData:要解密的字符串
     * @return
     */
    public String decrypt(PrivateKey priKey,String cipherData) {
        try {
            //init engine
            SM2Engine sm2Engine = MySm2Engine.createMySm2Engine(null,priKey,MySm2Engine.Type_Decode);

            //decrypt data
            byte[] cipherDataByte = Hex.decode(cipherData);
            byte[] bytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
            return new String(bytes, StandardCharsets.UTF_8);
        }catch (Exception e) {
            System.out.println("SM2解密失败:");
        }
        return null;
    }

    /**
     * 测试函数
     */
    public static void Sm2Test() {
        String dataStr = "hello ,2023!";
        try {
            Sm2CryptTools sm2CryptTools= new Sm2CryptTools();
            KeyPair keyPair = sm2CryptTools.mKeyPair;

            System.out.println("原始明文:" + dataStr);
            String resData = sm2CryptTools.encrypt(keyPair.getPublic(),dataStr);
            System.out.println("SM2加密后密文:" + resData);

            String resData2 = sm2CryptTools.decrypt(keyPair.getPrivate(),resData);
            System.out.println("SM2解密后明文:" + resData2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 主函数
     * @param args
     */
    public static void main(String[] args) {
        Sm2Test();
    }

}

工具类中,调用了自定义的MySm2Engine类,
MySm2Engine.java代码如下:

package com.abc.smutilstest;

import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.spec.ECParameterSpec;

import java.security.*;

/**
 * SM2引擎类
 */
public class MySm2Engine {
    public static final int Type_Encode = 0;
    public static final int Type_Decode = 1;

    /**
     * 创建一个SM2引擎
     * @param pubKey
     * @param priKey
     * @param enOrde
     * @return
     * @throws Exception
     */
     public static SM2Engine createMySm2Engine(PublicKey pubKey,PrivateKey priKey,int enOrde) throws Exception {
         if (enOrde == Type_Encode) {
             ECPublicKeyParameters ecPublicKeyParameters = null;
             if (pubKey instanceof BCECPublicKey) {
                 BCECPublicKey bcPubKey = (BCECPublicKey) pubKey;
                 ECParameterSpec ecParameterSpec = bcPubKey.getParameters();
                 ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                         ecParameterSpec.getG(), ecParameterSpec.getN());
                 ecPublicKeyParameters = new ECPublicKeyParameters(bcPubKey.getQ(),ecDomainParameters);
             }
             SM2Engine sm2Engine = new SM2Engine();
             sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
             return sm2Engine;
         }else {

             BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) priKey;
             ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters();
             ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                     ecParameterSpec.getG(), ecParameterSpec.getN());
             ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(),
                     ecDomainParameters);
             SM2Engine sm2Engine = new SM2Engine();
             sm2Engine.init(false, ecPrivateKeyParameters);
             return sm2Engine;
         }
     }
}

测试结果:
运行Sm2CryptTools中的main函数,结果如下:

原始明文:hello ,2023!
SM2加密后密文:04311f2333787826663e3347ae00aaceb4c48babbbef89df0ba54be00115ea0a0953021f1a10c5f4d7fbc5c365724131fd505f5cb019f13b455c06a0832124042845c683c90d9ebc6174199131f7cf586853fa26c6bae7e07dde4acf7fb049e5b46403103184b93b410b29342d
SM2解密后明文:hello ,2023!

总结

近几年,已经开始了加密算法国产替代,其中,SM2算法作为非对称算法,担任了重要的角色。很多具有密码资质的安全产品中,也都广泛运用了SM2算法。

国产安全,砥砺前行!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

国密算法(SM2)java语言的实现:利用bcprov库来实现SM2算法,非对称算法 的相关文章

  • px4 offboard外部控制仿真

    官网中http dev px4 io en ros mavros offboard html xff0c 只给示例代码 xff0c 却不告诉怎么用 xff0c 实在有点坑 xff0c 还好参照网上的一些博客 xff0c 找到了使用方法 首先
  • POST和GET方法的区别与联系

    错误的一个理论就是 xff0c get是从服务器拿数据 xff0c 而post是给服务器传数据 两者其实都是从服务器端拿数据 xff0c 只是一些细节不同罢了 历史 get和post是HTTP与服务器交互的方式 xff0c 说到方式 xff
  • Dronekit 搭配使用Ardupilot 和 PX4

    Dronekit是一个与无人机飞控搭配使用 xff0c 方便开发者使用代码控制无人机 个人认为它会比搭建ros来控制无人机更容易上手一些 对于Dronekit xff0c PX4被支持的较少 xff0c 不可以进行模式切换 xff0c 而对
  • 堆栈存放什么

    此乃转载别人发表 xff0c 作为知识点保存积累 一 xff1a 概念 1 栈 xff1a 当程序进入一个方法时 xff0c 会为这个方法单独分配一块私属存储空间 xff0c 用于存储这个方法内部的局部变量 xff0c 当这个方法结束时 x
  • 嵌入式实时操作系统ucosii原理及应用(任哲)-- --阅读笔记2

    本文是 嵌入式实时操作系统ucosii原理及应用 xff08 任哲 xff09 一书第三章的阅读笔记 xff0c 知识点多为摘录 xff0c 若希望深入了解 xff0c 请购买该书认真研读 由于一些知识比较零散 xff0c 记起来不大方便
  • 如何做项目总结与汇报

    在我们测试工作过程中 xff0c 由于公司业务发展 xff0c 快速迭代等原因 xff0c 我们遇到的项目以小项目居多 更新界面元素 xff0c 上个活动页 xff0c 优化一下原有的功能等等 xff0c 加上事情繁琐 xff0c 任务多
  • 手机安装linux deploy 安装和配置

    最近在淘了一款二手三星的sw 2014 正好最近正在研究智能家居 就想用它来搭建domoticz来管理 xff0c 虽然手头也有一块吃灰的树莓派3b 但是觉得用树莓派搭建有点浪费 xff0c 索性就用这款手机 为什么不用temux xff1
  • 国家分级保护规范要求解读

    仅就项目建设流程而言 xff0c 涉密信息系统建设使用单位应依据 涉及国家秘密的信息系统分级保护管理办法 国保发 2005 16号 确定系统等级 xff0c 结合本单位业务需求和涉密信息制定安全保密需求 xff0c 依据国家保密标准 BMB
  • PX4 编译分析之Airframe文档生成

    PX4 编译分析之Airframe文档生成 本文假设已经阅读了 PX4 的 1 Makefile分析 2 CMakeLists txt分析 这里要分析的是 make airframe metadata 的指令 在 Makefile 文件中找
  • PX4编译文件 Makefile 剖析

    PX4编译文件 Makefile 剖析 当我们执行 cd Firmware进入PX4源码目录 然后make 的时候 我们会看到一串输出基本如下 第一次编译会有更多的输出 2 Built target df driver framework
  • 如何使用vscode运行和调试c/c++程序

    众所周知 vscode是个万金油 xff0c 而且体型轻巧 xff0c 拓展插件多 xff0c 非常适合初学者编程 那么如何使用vscode进行c c 43 43 程序的运行 xff1f 首先必须确保mingw64正确安装 通过以下链接下载
  • PX4 CMakeLists.txt 文件剖析

    PX4 CMakeLists txt 文件剖析 前面对于 PX4 的 Makefile 已经做了比较详细的分析 见这里 这里进一步对 PX4 的 CMakeLists txt 文件结构进行进一步的分析 1 CMake 简述 CMake 是一
  • pymavlink 源码剖析(一)之XML文件的数据解析

    文章目录 1 引言2 pymavlink 的代码自动生成方法3 XML 文件的数据解析3 1 XML 文件预处理3 2 解析 XML 的数据3 2 1 依据协议版本初始化一些版本特征变量3 2 2 解析 XML 文件3 2 3 对解析后结果
  • MAVLink 协议解析之XML定义篇

    文章目录 1 MAVLink XML 文件的基本结构2 message3 enum 1 MAVLink XML 文件的基本结构 下面的代码块是 mavlink 消息定义的 xml 数据文档 代码块 1 span class token pr
  • pymavlink 源码剖析(二)之生成代码

    文章目录 1 引言2 C 代码生成3 generate one 函数分析4 MAVTemplate5 头文件生成 相关 xff1a pymavlink 源码剖析 一 xff09 之XML文件的数据解析MAVLink 协议解析之原理篇 MAV
  • Windows 10 下基于WSL的开源飞控开发环境配置(Ardupilot/PX4)

    目录 0 环境1 环境概述2 配置 WSL2 1 安装 WSL22 2 安装工具链 3 配置VS Code 0 环境 Windows 10 build version gt 61 18917 1 启动 cmd 后输出的第一行文字便是 Win
  • caffe,caffe2 and pytorch

    1 Difference caffe and caffe2 Caffe2 improves Caffe 1 0 in a series of directions 支持大规模分布式训练移动平台的部署在CPU 和 CUDA 之外的新的硬件类型
  • Windows 平台下基于MinGW和Qt 的OpenCV 之CMake 项目配置

    1 MinGW 编译OpenCV 参考其他教程 2 添加系统环境变量 OpenCV DIR 如果有执行 mingw32 make install xff0c 则为 build 目录下install 文件的完整路径 xff0c 如 D ope
  • ubuntu 上NVIDIA驱动和CUDA9.0 的坑之一二

    1 参考链接 1 NVIDIA 官方CUDA安装文档 http docs nvidia com cuda cuda installation guide linux index html 2 NVIDIA 对XFree86 下安装驱动的说明
  • 欧拉角奇异性产生的原因

    1 欧拉角奇异性的原因 1 1 奇异性的定义 奇异性 xff0c 英文Singularity wiki中的解释为 In mathematics a singularity is in general a point at which a g

随机推荐

  • 数据结构----依据出栈顺序判断所需的最少栈空间

    1 问题描述 问题 若元素 a b c d e f g 顺序进栈 xff0c 且出栈顺序是 b d c f e a g 则栈的容量至少是 答案 xff1a 3 2 解法描述与分析 2 1 解法描述 记 1 2 3 4 5 6 分别对应 a
  • error: ‘usleep’ was not declared in this scope

    报错 error usleep was not declared in this scope 解决办法 在出错程序的头文件中加入即可 span class token macro property span class token dire
  • Ubuntu 安装 cuda 时卡在登录界面(login loop)的解决方案之一

    当安装 cuda 时 xff0c 需要我们需要安装NVIDIA driver driver 用来支撑cuda 库的调用 xff0c 在满足官方文档 xff08 见 Table1 xff09 对于cuda 版本对于driver版本的要求情况下
  • QT开发--串口助手的编写

    一 创建工程 正常创建一个widget项目工程 xff0c 控件的方式进行代码研究 创建好编译测试一下工程 可以编译进行下一步操作 二 串口UI界面设计 1 选择ui控件 串口接收下位机数据显示界面控件 选择容器 波特率 串口号 数据位等多
  • 又是一年,我的2013年终总结

    昨天是冬至 xff08 2013年的12月22日 xff09 xff0c 日历摆了乌龙 xff0c 不少人提前把节给过了 xff0c 感觉稀里糊涂的 xff0c 也正如自己这一年的心情一样 xff0c 再过一个星期2013年也就算落下帷幕了
  • 按位与、按位异或、按位取反

    amp 按位与 按位或 按位异或 1 按位与运算 按位与运算符 34 amp 34 是双目运算符 其功能是参与运算的两数各对应的二进位相与 只有对应的两个二进位均为1时 xff0c 结果位才为1 xff0c 否则为0 参与运算的数以补码方式
  • VS断点设置无效的问题

    新的一年第一篇博客点的名字是已经被写烂了的题目 xff0c 并且也是浪费了网友无数的宝贵时间也很难解决的老大难问题 VS无法设定断点问题 先得吐槽一下CSDN的编辑器 xff0c 火狐下竟然无法显示工具条问题 xff0c 可能是因为xhEd
  • &与&&有什么区别?

    一 简要说明 按位与 xff1a a amp b 是把 a 和 b 都转换成二进制数然后再进行与的运算 xff1b 逻辑与 xff1a a amp amp b 就是当且仅当两个操作数均为 true 时 xff0c 其结果才为 true xf
  • VC在编译链接的无故死掉解决方案(防VC6卡死)

    现在网上有很多集成了SP6的VC6 xff0c 但是使用起来会有些某名奇妙的问题 xff0c 也许是我用的龙卷风那个版本不行 xff0c 最常见的就是VC在编译链接的时候经常无故死掉的问题了 xff0c 发生时候关也关不掉 xff0c 停也
  • 给纯SDK程序加上自己的ICO图标

    方法一 xff1a 给纯SDK程序加上自己的ICO图标 1 在项目中建一个resource h文件写入一句 define IDR MAINFRAME 128 2 在项目中建一个resource rc写入一句IDI ICO ICON DISC
  • Teechart 的用法详解:在VC6.0 跟Visual Studio 2005及之后版本的区别

    csdn的文件限制导致 xff0c gif图片不清晰 xff0c 我把文章放到简书上了 xff0c 地址 xff1a http www jianshu com p 2f3f6047d99a 什么时候开始接触teechart呢 xff0c 说
  • 为什么现在多数软件都默认选择安装目录为user下的AppData而非Progamfiles?

    为什么放弃默认选择Program Files 我一直百思不得其解 都是UAC xff08 用户权限控制 xff09 惹得祸 自从VISTA引入了权限机制UAC后 xff0c windows7及以后的系统版本 xff0c 对于Program
  • PIXHAWK飞控的外部控制

    PIXHAWK飞控可以运行PX4原生固件和APM固件 xff0c 我这里用的是PX4原生固件 xff0c 因为这款固件是专门为PIXHAWK量身打造的 xff0c 两者合起来性能更强 不过据说APM固件因为其比较完善 xff0c 更加稳定
  • 只知道用一样东西,不明白他的道理,实在不高明

    无论在哪个领域 xff0c 要抓住问题的本质 xff0c 切勿停留在表面 xff0c 要不断地深入下去 就这个小的领域来说 xff0c 你花个3 5年的时间挤进前20 是非常可能的 精通某一方面的技能 xff0c 才能使自己不容易被别人所替
  • 对VC++工程编译过程的梳理

    对VC 43 43 工程编译过程的梳理 VC 43 43 的项目和解决方案文件解读 xff0c 无非就是利用这些信息进行一个软件的编译 xff0c 这些文件里面是存放的项目的配置和工程的组织 xff0c 类似于makefile文件 但是只有
  • Teechart在VC++中使用的碎碎念

    今天再看官网推荐的Teechart的使用方式 xff0c 感觉他们还是推荐使用VC 43 43 6 0的导出头文件格式 xff0c 来引入所有的类 xff0c 并操作teechart控件 All the files necessary ca
  • 汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp这些都是什么意思啊?

    eax ebx ecx edx esi edi ebp esp等都是X86 汇编语言中CPU上的通用寄存器的名称 xff0c 是32位的寄存器 如果用C语言来解释 xff0c 可以把这些寄存器当作变量看待 比方说 xff1a add eax
  • 计算机CPU的工作原理动画

    一直在找有关CPU相关的工作原理动画 xff0c 终于找到了 喜欢这个的可以认真看看了 CPU工作原理系列动画下载
  • CSerialPort串口类最新修正版(解决关闭死锁问题)2014-01-11

    这是一份优秀的类文件 xff0c 好多的地方值得我们学习 xff0c 具体在多线程 xff0c 事件 xff0c 自定义消息 xff0c 类的封装方面等等 Remon提供的串口类网址为 xff1a http codeguru earthwe
  • 国密算法(SM2)java语言的实现:利用bcprov库来实现SM2算法,非对称算法

    SM2算法简介 随着密码技术和计算机技术的发展 xff0c 目前常用的1024位RSA算法面临严重的安全威胁 xff0c 我们国家密码管理部门经过研究 xff0c 决定采用SM2椭圆曲线算法替换RSA算法 SM2是非对称加密算法 xff1b