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

这篇具有很好参考价值的文章主要介绍了国密算法(SM2)java语言的实现:利用bcprov库来实现SM2算法,非对称算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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算法。

国产安全,砥砺前行!文章来源地址https://www.toymoban.com/news/detail-780649.html

到了这里,关于国密算法(SM2)java语言的实现:利用bcprov库来实现SM2算法,非对称算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 国密算法SM2/3/4简单比较,以及基于Java的SM4(ECB模式,CBC模式)对称加解密实现

    常用的国密算法包含SM2,SM3,SM4。以下针对每个算法使用场景进行说明以比较其差异 SM2:非对称加密算法,可以替代RSA 数字签名,SM2为非对称加密,加解密使用一对私钥和公钥,只有签名发行者拥有私钥,可用于加密,其他需要验证解密或验签者使用公钥进行。如果使用公

    2024年04月13日
    浏览(39)
  • vue前端国密SM2, SM4 算法实现

    整体加密逻辑是,首先生成16位key值 用SM2 公钥加密该key值,后端用sm2私钥 解密出key值,然后采用sm4方法根据key值对返回值进行加密,前端采用sm4 对后端返回结果进行解密进行前端展示 目前主要常用的国密算法有sm-crypto,gm-crypto,gm-crypt(SM4) 1、安装 sm-crypto 2、包装加解密

    2024年02月12日
    浏览(46)
  • java 国密算法工具类(支持SM2 SM3 SM4)

    前言 工具采用BC库实现,支持前后端加解密,前端建议使用sm-crypto 引入pom依赖 基本使用如下 国密SM2算法 国密SM3算法 国密SM4算法使用

    2024年02月13日
    浏览(49)
  • 国密SM2算法(JS加密,C#、Java解密)

    常见的渗透测试会将网站登录时密码使用明文传输视为风险。推荐使用国密算法或者RSA算法对密码进行加密传输。 RSA加密(JS加密,C#、Java解密)请参考《RSA对称加密(JS加密,C#、Java解密)》​​​​​​ 本文描述国密SM2算法的实现。 一、工作原理 前端js使用公钥进行加密

    2024年02月02日
    浏览(52)
  • 国密算法SM2实现基于hutool工具类

    首先引入maven 直接上代码

    2024年02月11日
    浏览(53)
  • Go实现国密算法SM2、SM3、SM4

    SM2椭圆曲线公钥密码算法 Public key cryptographic algorithm SM2 based on elliptic curves 遵循的SM2标准号为: GM/T 0003.1-2012、GM/T 0003.2-2012、GM/T 0003.3-2012、GM/T 0003.4-2012、GM/T 0003.5-2012、GM/T 0009-2012、GM/T 0010-2012 依赖包: github.com/tjfoc/gmsm/sm2 SM3密码杂凑算法 - SM3 cryptographic hash algorithm 遵循的SM

    2024年02月15日
    浏览(47)
  • 国密SM2: 加解密实现 java代码完整示例

    目录  具体Java代码SM2算法加解密实现Demo: pom依赖引入 :  国家密码管理局于2010年12月17日发布了SM2算法,并要求现有的基于RSA算法的电子认证系统、密钥管理系统、应用系统进升级改造,使用支持国密SM2算法的证书。    基于ECC椭圆曲线算法的SM2算法,则普遍采用256位密钥

    2024年02月13日
    浏览(44)
  • Python实现国家商用密码算法sm2/sm3/sm4/sm9(国密)

    2010 年开始,我国国家密码管理局就已经开始陆续发布了一系列国产加密算法,这其中就包括 SM1、SM2、SM3 、SM4、SM7、SM9、ZUC(祖冲之加密算法)等,SM 代表商密,即商业密码,是指用于商业的、不涉及国家秘密的密码技术。SM1 和 SM7 的算法不公开,其余算法都已成为 ISO/IEC

    2024年02月15日
    浏览(47)
  • 国密sm2公钥加密 私钥解密java代码实现

    目录 一、引入jar包 二、生成秘钥对,加解密工具类

    2024年02月11日
    浏览(67)
  • react+vue 前端国密算法sm2、sm3 、sm4的js ts实现

    1. 简单介绍下SM2 和 SM3 SM2 算法:是一种公钥加密算法,它的密钥长度为 256 位,安全性较高。可用于数字签名、密钥协商等场景。 SM3 算法:是一种对称加密算法,用于消息摘要和数字签名等场景。它的密钥长度为 256 位,安全性较高。SM3 算法与 SM2 算法相互配合,提高了整体

    2024年01月19日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包