国密SM2: 加解密实现 java代码完整示例

时间:2024-01-10 01:06:20 标签:  java  算法  

目录

 具体Java代码SM2算法加解密实现Demo:

pom依赖引入 : 

国家密码管理局于2010年12月17日发布了SM2算法,并要求现有的基于RSA算法的电子认证系统、密钥管理系统、应用系统进升级改造,使用支持国密SM2算法的证书。

  

基于ECC椭圆曲线算法的SM2算法,则普遍采用256位密钥长度,它的单位安全强度相对较高,在工程应用中比较难以实现,破译或求解难度基本上是指数级的。因此,SM2算法可以用较少的计算能力提供比RSA算法更高的安全强度,而所需的密钥长度却远比RSA算法低。 

对比项目ECC加密算法RSA加密算法
密钥长度256位2048位
CPU占用较少较高
内存占用较少较高
网络消耗较低较高
加密效率较高一般
破解难度具有数据特性,破解难度大相对ECC理论上容易些
抗攻击性一般
可扩展性一般
兼容范围支持新版浏览器和操作系统,但存在少数不支持平台,例如cPanel广泛支持

 具体Java代码SM2算法加解密实现Demo:

package org.example;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
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.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECGenParameterSpec;

/**
 * @ClassName SM2Utils
 * @Description SM2算法工具类
 */
public class SM2Utils {
    public static KeyPair createECKeyPair() {
        final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");

        // 获取一个椭圆曲线类型的密钥对生成器
        final KeyPairGenerator kpg;
        try {
            kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
            kpg.initialize(sm2Spec, new SecureRandom());

            return kpg.generateKeyPair();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String encrypt(String publicKeyHex, String data) {
        return encrypt(getECPublicKeyByPublicKeyHex(publicKeyHex), data, 1);
    }

    public static String encrypt(BCECPublicKey publicKey, String data, int modeType) {
        //加密模式
        SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;
        if (modeType != 1) {
            mode = SM2Engine.Mode.C1C2C3;
        }
        ECParameterSpec ecParameterSpec = publicKey.getParameters();
        ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                ecParameterSpec.getG(), ecParameterSpec.getN());
        ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(publicKey.getQ(), ecDomainParameters);
 
        SM2Engine sm2Engine = new SM2Engine(mode);

        sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
        byte[] arrayOfBytes = null;
        try {
            byte[] in = data.getBytes("utf-8");
        
            arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
        } catch (Exception e) {
            System.out.println("SM2加密时出现异常:" + e.getMessage());
            e.printStackTrace();
        }
        return Hex.toHexString(arrayOfBytes);
    }

    public static String decrypt(String privateKeyHex, String cipherData) {
        return decrypt(getBCECPrivateKeyByPrivateKeyHex(privateKeyHex), cipherData, 1);
    }

    public static String decrypt(BCECPrivateKey privateKey, String cipherData, int modeType) {
        //解密模式
        SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;
        if (modeType != 1)
            mode = SM2Engine.Mode.C1C2C3;
       
        byte[] cipherDataByte = Hex.decode(cipherData);
        ECParameterSpec ecParameterSpec = privateKey.getParameters();
        ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
                ecParameterSpec.getG(), ecParameterSpec.getN());
        ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(privateKey.getD(),
                ecDomainParameters);

        SM2Engine sm2Engine = new SM2Engine(mode);
        sm2Engine.init(false, ecPrivateKeyParameters);
        String result = null;
        try {
            byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
            result = new String(arrayOfBytes, "utf-8");
        } catch (Exception e) {
            System.out.println("SM2解密时出现异常" + e.getMessage());
        }
        return result;
    }
 
    private static X9ECParameters x9ECParameters = GMNamedCurves.getByName("sm2p256v1");

    private static ECParameterSpec ecDomainParameters = new ECParameterSpec(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN());

    public static BCECPublicKey getECPublicKeyByPublicKeyHex(String pubKeyHex) {
  
        if (pubKeyHex.length() > 128) {
            pubKeyHex = pubKeyHex.substring(pubKeyHex.length() - 128);
        }
        String stringX = pubKeyHex.substring(0, 64);
        String stringY = pubKeyHex.substring(stringX.length());
        BigInteger x = new BigInteger(stringX, 16);
        BigInteger y = new BigInteger(stringY, 16);
  
        ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(x9ECParameters.getCurve().createPoint(x, y), ecDomainParameters);
    
        return new BCECPublicKey("EC", ecPublicKeySpec, BouncyCastleProvider.CONFIGURATION);
    }

    public static BCECPrivateKey getBCECPrivateKeyByPrivateKeyHex(String privateKeyHex) {
        BigInteger d = new BigInteger(privateKeyHex, 16);
        ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(d, ecDomainParameters);
        return new BCECPrivateKey("EC", ecPrivateKeySpec, BouncyCastleProvider.CONFIGURATION);
    }

    public static void main(String[] args) {
        String publicKeyHex = null;
        String privateKeyHex = null;
        KeyPair keyPair = createECKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        if (publicKey instanceof BCECPublicKey) {
            //获取65字节非压缩缩的十六进制公钥串(0x04)
            publicKeyHex = Hex.toHexString(((BCECPublicKey) publicKey).getQ().getEncoded(false));
            System.out.println("SM2公钥:" + publicKeyHex);
        }
        PrivateKey privateKey = keyPair.getPrivate();
        if (privateKey instanceof BCECPrivateKey) {
            //获取32字节十六进制私钥串
            privateKeyHex = ((BCECPrivateKey) privateKey).getD().toString(16);
            System.out.println("SM2私钥:" + privateKeyHex);
        }

        /**
         * 公钥加密
         */
        String data = "=========需要加密的数据=========";

        //将十六进制公钥串转换为 BCECPublicKey 公钥对象
        String encryptData = encrypt(publicKeyHex, data);
        System.out.println("加密结果:" + encryptData);

        /**
         * 私钥解密
         */
        //将十六进制私钥串转换为 BCECPrivateKey 私钥对象
        data = decrypt(privateKeyHex, encryptData);
        System.out.println("解密结果:" + data);
    }
}

pom依赖引入 :

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

 

来源:https://blоg.сsdn.nеt/оh_соding/аrtiсlе/dеtаils/129182595

智能推荐

秦医如毒&#xff0c;无药可解。 话不多说&#xff0c;先上需要用

标签:前端  java  spring  后端  tomcat  

//仿射密码加密算法#include &

标签:c++  java  蓝桥杯  

几何学基础欧式几何从一点向另一点可以引一条直线。任意线段能无限延伸成一条直线。给定任意线段,可以以其一个端点作为圆心,该线段作为半径作一个圆。所有直角都相等。若两条直线都与第三条直线相交,并且在同一边的内角之和小于两个直角,则这两条直线在这一边必定相交。罗巴切夫斯基几何第五公设不能被证明。在新的公理体系中展开的一连串推理,得到了一

标签:加密算法  

功能描述 使用shell opensll对明文进行RSA加密&#xff0c;将密

标签:java  开发语言  RSA  加密解密  

2023.10.25今天我学习了如何使用sm4进行加密解密&#xff1a; 注意&#

标签:javascript  前端  开发语言  

什么是代码加密?基于云效 Codeup的代码仓库加密是如何实现的?在互联网快速发展的时代,代码是企业最核心的资产,代码安全也是首当其冲;为了保护企业代码安全,各公司使出的手段也是五花八门,但未必安全,而云端加密代码服务是阿里云 云效团队的自研产品,是目前国内率先支持代码加密的托管服务,能够有效的阻断代码对运维人员的可见性

标签:代码  如何实现  仓库  Codeup  

C#.NET 国密SM4 CBC 对称加解密 与JAVA互通 ver:20231103&nbsp;.NET 环境:.NET6 控制台程序(.net core)。JAVA 环境:JAVA8,带maven 的JAVA控制台程序。&nbsp;简要解析:1:加密的KEY、明文等输入参数都需要string转 byte [] ,要约定好编码,如:UTF8。2:加密后的输出参数:byte [] ,在传输时需要转为string,要约定好编码,如:16进制字符串。&nbsp;3: cbc 的 KEY 和 IV 长度都是16.&nbsp;这里演示的

标签:对称  加解密  NET  国密  CBC  

具体的加密算法可以可自行查询其区别,这里只是抛砖引玉,大部分加密方法基本都能通过改变传入参数来实现。C#相关类文档:&nbsp;System.Security.Cryptography 命名空间 | Microsoft LearnNode JS相关文档:Crypto | Node.js v16.20.0 Documentation (nodejs.org)&nbsp;C#加密函数: 1 using

标签:加密解密  Node  JS  DES  

猜你喜欢

为何要对代码加密&

标签:安全  python  python代码加密  

RSA加解密中必须考虑到的**长度、明文长度和密文长度问题。明文长度需要小于**长度&#xff0c;

标签:php  golang  java  

在日常开发过程中&#xff0c;总会遇到需要加密解密的需求&#xff0c;这里我整理了C#常用的加密

标签:C# 分享  c#  加密解密  RAS  

AES-128-ECB和AES-256-CBC是两种常见的AES加密模式&#xff0c;它们在加

标签:php  加密  php  开发语言  同态加密  hash-index  哈希算法  

帮一个客户处理一个小程序bug修复,前面不知道客户是直接购买一个倒闭的公司产品,还是破解版本的。其中一些核心工具类代码进行了加密,通过排查就找到了 Swoole Compiler&nbsp;今天演示下如何进行代码加密:大致步骤 如下:注册&nbsp;Swoole Compiler&nbsp; 账号 地址:Swoole-Compiler - 最佳 PHP 源代码加密编译器源码进行压缩打包 上传后台进行工具加密得到加密的文件安装配置PHP.ini 环境进行访问模块正常

标签:实战  过程  代码  php  Swoole  

调用方式&#xff1a;

标签:typescript  

问题&#xff1a;         在使用Django学习制作网站时候&#xf

标签:python  Django  python  后端  安全  

定义JNI方法 companion object{ init {

标签:android  算法  OpenSSL  JNI  

 AES算法全称Advanced Encryption Standard。它是典型的“对称加密算法”

标签:android  android  

 前端部分注意看填充是pkcs7 有个前提&#xff0c;要看前端有没有转成hex格

标签:前端  javascript  AES  加密解密AES  php的AES加解密  

前言 先给大家看下效果&#xff0c;原本我们的请求是这样子的

标签:java  java  加解密  加密  解密  

1. 介绍 在Java开发的过程中&#xff0c;很多场景下都需要加密解密。

标签:技术  安全  

摘要:数据加密作为有效防止未授权访问和防护数据泄露的技术,在各种信息系统中广泛使用。作为信息系统的核心,GaussDB(DWS)数仓也提供数据加密功能,包括透明加密和使用SQL函数加密。本文分享自华为云社区《看GaussDB(DWS)如何使用SQL加密函数实现数据列加解密》,作者:Hello EI。数据加密作为有效防止未授权访问和防护数据泄露的技术,在各种信息系统中广泛使用。作为信息系统的核心,GaussDB(DWS)数仓也提供

标签:函数  加解密  数据  云小课  sql  

1. 介绍在我们日常的Java开发中,免不了和其他系统的业务交互,或者微服务之间的接口调用如果我们想保证数据传输的安全,对接口出参加密,入参解密。但是不想写重复代码,我们可以提供一个通用starter,提供通用加密解密功能2. 前置知识2.1 hutool-crypto加密解密工具hutool-crypto提供了很多加密解密工具,包括对称加密,非对称加密,摘要加密等等,这不做详细介绍。2.2 request流只能读取一次的问题2.2.1 问题:在接口调用链中,request的请求流只能调用一次,处理之后,如果之后还需要用到请

标签:接口  加密解密  SpringBoot接口  加密解密  SpringBoot  

hmac   Hash-based Message Authentication Code

标签:c++  开发语言  

一、PassPhrase加密1.1、概要简述1)对于不涉及证书及密钥的应急的数据加密,可以直接基于用户提供的密码来加密和解密数据。2)通行短语(PassPhrase)是允许存在空格的密码。这个PassPhrase不会存储在数据库中,因而也就意味着不会被使用存储的系统数据破解。同时,可以使用空格创建一个长的、易于记忆的句子来加密和解密敏感数据。3)PassPhrase支持的数据列类型有nvarchar、varchar、nchar、char、varbinary、binary。1.2、加密函数CREATE

标签:sql  Server  

相关问题

相关文章

热门文章

推荐文章

相关标签