springboot使用国产加密算法方式,sm2和sm3加解密demo

 更新时间:2023年07月19日 09:49:29   作者:yy1209357299  
这篇文章主要介绍了springboot使用国产加密算法方式,sm2和sm3加解密demo,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

需求

前后端交互的加解密算法,要求使用国产的

1、SM1分组密码算法

SM1是由国家密码管理局编制的一种商用密码分组标准对称算法,分组长度和密钥长度均为128位,算法的安全保密强度及相关软硬件实现性能与AES算法相当,目前该算法尚未公开,仅以IP核的形式存在于芯片中,调用该算法时,需要通过加密芯片的接口进行调用。

2、*SM2公钥密码算法

SM2算法是国家密码据于2010年12月17日发布的国密标准椭圆曲线加密算法,是一种基于ECC算法的非对称加密算法,SM2椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,包括SM2-1椭圆曲线数字签名算法,SM2-2椭圆曲线密钥交换协议,SM2-3椭圆曲线公钥加密算法,分别用于实现数字签名密钥协商和数据加密等功能。

SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,对于一般椭圆曲线的离散对数问题,目前只存在指数级计算复杂度的求解方法。

与大数分解问题及有限域上离散对数问题相比,椭圆曲线离散对数问题的求解难度要大得多。

因此,在相同安全程度要求下,椭圆曲线密码较其他公钥密码所需的秘钥规模要小得多。

相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高。

其加密强度为256位,密钥长度短,安全程度高,可用于数字签名、密钥交换、公钥加密。

3、*SM3密码杂凑算法

SM3是我国采用的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。

相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。

据国家密码管理局表示,其安全性及效率与SHA-256相当,也叫密码杂凑算法,属于哈希(摘要)算法的一种,功能与MD5,SHA-1相同。

对长度小于264比特的消息m,经过填充、压缩,生成256位杂凑值,和SM2算法一起被公布,该算法位不可逆的算法。

在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,可满足多种密码应用的安全需求,算法已公开。

4、*SM4分组密码算法

SM4是国家密码管理局发布的分组密码算法,于2012年3月正式公布。

与DES和AES算法类似,SM4是一种分组密码算法。其分组长度为128bit,密钥长度也为128bit。

SM4算法加/解密算法是对合运算,只是使用轮密钥相反,其中解密轮密钥是加密轮密钥的逆序。

加密算法与密钥扩展算法均采用32轮非线性迭代结构(Feistel),以字(32位)为单位进行加密运算,每一次迭代运算均为一轮变换函数F。

目前主要用于无线局域网产品。

方案

使用场景:前后端交互使用sm2,后端存储密码时使用sm3

1、pom依赖

<dependency>
     <groupId>org.bouncycastle</groupId>
     <artifactId>bcprov-jdk15on</artifactId>
     <version>1.60</version>
</dependency>

2、demo示例

public static void main(String[] args) throws InvalidCipherTextException {
        System.out.println("sm2测试开始-----------");
        X9ECParameters sm2EcParameters = GMNamedCurves.getByName("sm2p256v1");
        ECDomainParameters domainParameters = new ECDomainParameters(sm2EcParameters.getCurve(),sm2EcParameters.getG(),sm2EcParameters.getN());
        ECKeyPairGenerator keyPairGenerator =new ECKeyPairGenerator();
        try {
            keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
            AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
            //私钥
            BigInteger privateKey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
            String privateKeyHex = privateKey.toString(16);
            System.out.println("私钥:" + privateKeyHex);
            //公钥
            ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
            String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
            System.out.println("公钥:" + publicKeyHex);
            String str = SM2Util.encrypt("test",publicKeyHex);
            System.out.println("加密结果:"+str);
            try{
                String res = SM2Util.decrypt(str,privateKeyHex);
                System.out.println("解密结果:"+res);
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println("sm2测试结束-----------");
            System.out.println("sm3测试开始-----------");
            String sm3 = SM3Util.sm3Sign("test");
            System.out.println("sm3加密结果"+sm3);
            if(SM3Util.sm3Verify("test",sm3)){
                System.out.println("sm3验证成功");
            }else {
                System.out.println("sm3验证失败");
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

3、结果

sm2测试开始-----------
私钥:bdda9f26ae5884e3f5410902aec78cab6c3f4a7c9d9578e6a9c60ae977d6d645
公钥:041870142d71f518ce9bd6458b4b41b4d49e7fbfd9a14440eb49ed9bbb352e72739d2e2369722ba381db2a7add5093c7a976df49496cb5c08a56e87db877f4e866
加密结果:0445fd5bce247f30cd507314830f57d3278dfdfab3e8fdc6acb93c60a3a4b6bbc09150c065153389d7b0c3581a0a0fd5c3ffe59ed53855a289a98ce9705a5230b752aa8535980ba08db6319eef0f3c1140ccd3d0849f0c78a4478189c1736de07b27254794929c9de9
解密结果:test
sm2测试结束-----------
sm3测试开始-----------
sm3加密结果55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23
sm3验证成功

4、前端加密

const sm2 = require('sm-crypto').sm2
const cipherMode = 0 // 1 - C1C3C2,0 - C1C2C3,默认为1,这里用0

加密

let base = Base64.encode(msgString);
let encryptData = sm2.doEncrypt(base, publicKey, cipherMode) // 加密结果
conso.log("加密结果:",encryptData);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mybatis如何使用Criteria的and和or进行联合查询

    mybatis如何使用Criteria的and和or进行联合查询

    这篇文章主要介绍了mybatis如何使用Criteria的and和or进行联合查询,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 一文详解JavaWeb过滤器(Filter)

    一文详解JavaWeb过滤器(Filter)

    本文主要介绍了一文详解JavaWeb过滤器(Filter),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • Spring Boot 3.0 + MyBatis-Plus全家桶实战详细代码

    Spring Boot 3.0 + MyBatis-Plus全家桶实战详细代码

    MyBatis-Plus是一个MyBatis的增强工具,是国内人员开发的MyBatis增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生,这篇文章主要介绍了Spring Boot 3.0 + MyBatis-Plus全家桶的相关资料,需要的朋友可以参考下
    2025-10-10
  • Java之synchronized(含与ReentrantLock的区别解读)

    Java之synchronized(含与ReentrantLock的区别解读)

    文章主要介绍了`synchronized`和`ReentrantLock`的区别,包括它们的实现原理、公平性、灵活性、可中断性等方面,同时,文章详细解释了`synchronized`的使用方法,包括修饰实例方法、静态方法和代码块的情况,以及如何分析代码是否互斥和可重入性
    2025-01-01
  • springboot集成nacos的配置方法

    springboot集成nacos的配置方法

    这篇文章主要介绍了springboot集成nacos的配置方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 8个简单部分开启Java语言学习之路 附java学习书单

    8个简单部分开启Java语言学习之路 附java学习书单

    8个简单部分开启Java语言学习之路,附java学习书单,这篇文章主要向大家介绍了学习java语言的方向,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 浅谈java并发之计数器CountDownLatch

    浅谈java并发之计数器CountDownLatch

    CountDownLatch是通过一个计数器来实现的,当我们在new 一个CountDownLatch对象的时候需要带入该计数器值,该值就表示了线程的数量。下面我们来深入了解一下吧
    2019-06-06
  • Java并发之Condition案例详解

    Java并发之Condition案例详解

    这篇文章主要介绍了Java并发之Condition案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • Java编程实现从给定范围内随机N个不重复数生成随机数的方法小结

    Java编程实现从给定范围内随机N个不重复数生成随机数的方法小结

    这篇文章主要介绍了Java编程实现从给定范围内随机N个不重复数生成随机数的方法,结合实例形式较为详细的分析了java根据指定范围生成不重复随机数的相关操作技巧,需要的朋友可以参考下
    2017-04-04
  • Java方法能定义多少个参数你知道吗

    Java方法能定义多少个参数你知道吗

    这篇文章主要给大家介绍了关于Java方法能定义多少个参数的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09

最新评论