注意:本博文仅仅说明SM2的使用,应用场景等,不研究其算法。

SM2是非对称加密算法,对应应用层程序员来说,使用逻辑和RSA一样。

他的最主要的功能:

①非对称加密;

②签名和验签

对于应用层程序员来说,必须熟悉他的使用,以及他的应用领域,一般在写一个安全的应用时,如果单单使用SM2是不安全的,基本上SM2、SM3、SM4都会同时使用。一般都是用SM4对数据内容加密,使用SM3,对内容进行摘要,再使用SM2,对摘要进行签名。这个是数据发送端做的事情。接收端,先用SM2,对摘要进行验签,验签成功后,就做到了防抵赖,对发送过来的内容进行SM3摘要,看下生成的摘要和验签后的摘要是否一致,用于防篡改。

大体逻辑就是这样的。

另外SM4在加密解密需要相同的密钥,这个我们可以通过编写密钥交换模块实现生成相同的密钥。用于SM4对称加密。

对于应用层来说,说白了就是把RSA换成SM2、把MD5换成SM3,把AES换成SM4,这下大家明白了吧。

这里使用hutool这个库进行SM2的操作!

关于非对称加密的公钥和私钥,可以使用hutool生成,也可以使用openssl生成

openssl生成SM2公钥私钥:

openssl ecparam -genkey -name SM2 -out priv.key
openssl ec -in priv.key -pubout -out pub.key

生成的密钥如下:

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJ
G9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==
-----END PUBLIC KEY-----
-----BEGIN EC PARAMETERS-----
BggqgRzPVQGCLQ==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9V
AYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428
SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==
-----END EC PRIVATE KEY-----

关于非对称还要注意几点:

公钥是通过私钥产生的;

公钥加密,私钥解密是加密的过程

私钥加密,公钥解密是签名的过程;

源码如下:

package cn.it1995;import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;import javax.swing.*;
import java.security.KeyPair;public class Main {static String txt = "Hello World";/**** 随机生成的密钥对加密或解密*/public static void test1(){SM2 sm2 = SmUtil.sm2();System.out.println("私钥:" + sm2.getPrivateKey());System.out.println("公钥:" + sm2.getPublicKey());String encryptStr = sm2.encryptBcd(txt, KeyType.PublicKey);String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));System.out.println("密文:" + encryptStr);System.out.println("明文:" + decryptStr);}/**** 自定义密钥对加密或解密*/public static void test2(){KeyPair pair = SecureUtil.generateKeyPair("SM2");byte[] privateKey = pair.getPrivate().getEncoded();byte[] publicKey = pair.getPublic().getEncoded();System.out.println("私钥:");for(Integer i = 0; i < privateKey.length; i++){System.out.print(privateKey[i] + " ");}System.out.println();System.out.println("公钥:");for(Integer i = 0; i < publicKey.length; i++){System.out.print(publicKey[i] + " ");}System.out.println();SM2 sm2 = SmUtil.sm2(privateKey, publicKey);String encryptStr = sm2.encryptBcd(txt, KeyType.PublicKey);String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));System.out.println("密文:" + encryptStr);System.out.println("明文:" + decryptStr);}/**** 使用OpenSSL生成的SM2公钥和私钥加密或解密*/public static void test3(){String privateKey = "MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9VAYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";SM2 sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));String encryptStr = sm2.encryptBcd(txt, KeyType.PublicKey);String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));System.out.println("密文:" + encryptStr);System.out.println("明文:" + decryptStr);}/**** 随机密钥 签名和验签*/public static void test4(){SM2 sm2 = SmUtil.sm2();String sign = sm2.signHex(HexUtil.encodeHexStr(txt));System.out.println("sign:" + sign);boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(txt), sign);System.out.println("verify:" + verify);}/**** 自定义密钥对 签名和验签*/public static void test5(){KeyPair pair = SecureUtil.generateKeyPair("SM2");final SM2 sm2 = new SM2(pair.getPrivate(), pair.getPublic());byte[] sign = sm2.sign(txt.getBytes());System.out.println("sign");for(Integer i = 0; i < sign.length; i++){System.out.print(sign[i] + " ");}System.out.println();boolean verify = sm2.verify(txt.getBytes(), sign);System.out.print("verify:" + verify);}/*** OpenSSL密钥对 签名和验签*/public static void test6(){String privateKey = "MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9VAYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";SM2 sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));byte[] sign = sm2.sign(txt.getBytes());System.out.println("sign");for(Integer i = 0; i < sign.length; i++){System.out.print(sign[i] + " ");}System.out.println();boolean verify = sm2.verify(txt.getBytes(), sign);System.out.print("verify:" + verify);}/**** 分开的:私钥签名,公钥验签* 密钥使用OpenSSL生成*/public static void test7(){String privateKey = "MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9VAYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";SM2 sm2Sign = SmUtil.sm2(Base64.decode(privateKey), null);sm2Sign.usePlainEncoding();byte[] sign = sm2Sign.sign(txt.getBytes(), null);System.out.println("sign");for(Integer i = 0; i < sign.length; i++){System.out.print(sign[i] + " ");}System.out.println();SM2 sm2 = SmUtil.sm2(null, Base64.decode(publicKey));sm2.usePlainEncoding();boolean verify = sm2.verify(txt.getBytes(), sign);System.out.print("verify:" + verify);}public void test8(){}public static void main(String[] args) {test1();System.out.println("--------------------华丽的分割线------------------------");test2();System.out.println("--------------------华丽的分割线------------------------");test3();System.out.println("--------------------华丽的分割线------------------------");test4();System.out.println("--------------------华丽的分割线------------------------");test5();System.out.println("--------------------华丽的分割线------------------------");test6();System.out.println("--------------------华丽的分割线------------------------");test7();}
}

程序运行如下:

D:\java8\content\bin\java.exe -javaagent:D:\idea\content\lib\idea_rt.jar=50163:D:\idea\content\bin -Dfile.encoding=UTF-8 -classpath D:\java8\content\jre\lib\charsets.jar;D:\java8\content\jre\lib\deploy.jar;D:\java8\content\jre\lib\ext\access-bridge-64.jar;D:\java8\content\jre\lib\ext\cldrdata.jar;D:\java8\content\jre\lib\ext\dnsns.jar;D:\java8\content\jre\lib\ext\jaccess.jar;D:\java8\content\jre\lib\ext\jfxrt.jar;D:\java8\content\jre\lib\ext\localedata.jar;D:\java8\content\jre\lib\ext\nashorn.jar;D:\java8\content\jre\lib\ext\sunec.jar;D:\java8\content\jre\lib\ext\sunjce_provider.jar;D:\java8\content\jre\lib\ext\sunmscapi.jar;D:\java8\content\jre\lib\ext\sunpkcs11.jar;D:\java8\content\jre\lib\ext\zipfs.jar;D:\java8\content\jre\lib\javaws.jar;D:\java8\content\jre\lib\jce.jar;D:\java8\content\jre\lib\jfr.jar;D:\java8\content\jre\lib\jfxswt.jar;D:\java8\content\jre\lib\jsse.jar;D:\java8\content\jre\lib\management-agent.jar;D:\java8\content\jre\lib\plugin.jar;D:\java8\content\jre\lib\resources.jar;D:\java8\content\jre\lib\rt.jar;D:\IDEAProject\SM2Demo\target\classes;D:\newGenRepository\repository\cn\hutool\hutool-all\5.7.6\hutool-all-5.7.6.jar;D:\newGenRepository\repository\org\bouncycastle\bcprov-jdk15to18\1.68\bcprov-jdk15to18-1.68.jar cn.it1995.Main
私钥:EC Private Key [69:a6:2d:32:b5:e8:19:e0:69:a8:a1:f4:ad:2e:60:eb:9d:49:b2:2a]X: 8b9cd15f1f6cc97674c0f0dd1613890700805ecbfb7368eade20fa91565c1d49Y: 7ca52554e76f04471b69ef8b042080e596937d4d7fd3311c642d5b6a2b2c781d公钥:EC Public Key [69:a6:2d:32:b5:e8:19:e0:69:a8:a1:f4:ad:2e:60:eb:9d:49:b2:2a]X: 8b9cd15f1f6cc97674c0f0dd1613890700805ecbfb7368eade20fa91565c1d49Y: 7ca52554e76f04471b69ef8b042080e596937d4d7fd3311c642d5b6a2b2c781d密文:043AB278DCB9C19E64251B406DB855873AB65BD302CD321ACB509A12449559AD67C7EB8CA0FBE290D06BA9750D38EB70A69DC14C0ECF01803DA4971D471F0C3303D0C69A1001DACC048AECAA0F191196041DA367BBEB100F7C02506B57F51568F17A7C1024E90D30F7D20006
明文:Hello World
--------------------华丽的分割线------------------------
私钥:
48 -127 -109 2 1 0 48 19 6 7 42 -122 72 -50 61 2 1 6 8 42 -127 28 -49 85 1 -126 45 4 121 48 119 2 1 1 4 32 -88 107 3 126 93 -49 -79 -127 52 60 55 125 -50 38 78 68 -34 81 -84 -97 -82 69 0 3 -72 40 23 15 -41 112 -96 -97 -96 10 6 8 42 -127 28 -49 85 1 -126 45 -95 68 3 66 0 4 -35 21 15 107 92 -61 82 34 -25 34 24 42 122 -18 88 117 -49 -20 50 -92 -10 -99 77 46 -80 -20 -121 99 13 -114 54 -105 34 -1 -72 77 7 -87 -112 84 -91 64 71 91 40 -78 -126 119 10 -113 97 6 94 -47 12 -8 37 -11 -61 81 96 14 -51 -97
公钥:
48 89 48 19 6 7 42 -122 72 -50 61 2 1 6 8 42 -127 28 -49 85 1 -126 45 3 66 0 4 -35 21 15 107 92 -61 82 34 -25 34 24 42 122 -18 88 117 -49 -20 50 -92 -10 -99 77 46 -80 -20 -121 99 13 -114 54 -105 34 -1 -72 77 7 -87 -112 84 -91 64 71 91 40 -78 -126 119 10 -113 97 6 94 -47 12 -8 37 -11 -61 81 96 14 -51 -97
密文:049625A78A0D48E6C41F55A097E6039C84EE6EF402477A2ACB9FF3D319913731750F3ADAB9186190F0B9EDFBC91B66867A323FFE1C01B5F543ED52D27CFAFBE6E9D37FF3B698D4931196D8D68E81A70726DA67F4C4E59F0007AAA06459704DB40DF8E21E81A9970D35EFD0ED
明文:Hello World
--------------------华丽的分割线------------------------
密文:04D10EE79A33A1A8CE7407544908732F039C244C6FD04D59D5586B701455432209FA93B57142410E69B2BF1B8C8F8176FBDC8AB92FE07BD8C67F3FB121E10E58F1D66AD53E8FDB9408E9CF86E0B463F2968A166BF8F53D8EBEF97E37A325BD49C5F4D6A2AD06851F7DC7E158
明文:Hello World
--------------------华丽的分割线------------------------
sign:3044022025d780da4e9e9756966a5f9bfcfac402bd23fed5ef8e7430605aa409fbddf5ae0220230d911af4bfac036641968fffb7e4fabb17b7e40e85f506bffb8b67932139bf
verify:true
--------------------华丽的分割线------------------------
sign
48 70 2 33 0 -69 -7 -33 44 122 -10 73 60 14 7 -64 58 77 -57 6 -17 16 16 -78 6 114 -80 -100 -118 102 -70 -38 -90 26 -74 -118 91 2 33 0 -127 119 -13 -46 75 27 -52 79 98 42 -68 -44 35 7 -28 -128 -65 84 74 120 -116 -65 -97 77 32 -21 -7 23 -17 59 -84 124
verify:true--------------------华丽的分割线------------------------
sign
48 68 2 32 42 -28 -26 -47 -126 -12 81 -47 68 -80 62 106 -114 -96 -121 -117 -36 -76 77 -35 -106 4 15 103 67 28 -40 -11 -61 26 -96 31 2 32 87 97 -38 20 -111 33 -73 87 100 31 -123 71 110 -118 4 -32 -67 -35 -52 50 -66 -100 99 -83 4 -39 -64 -73 -97 -31 71 67
verify:true--------------------华丽的分割线------------------------
sign
-100 16 -120 93 -98 -23 -87 8 112 75 107 -14 -103 19 -38 -76 115 -86 -128 -120 -95 -20 97 64 123 11 125 -114 18 21 -48 6 87 15 -74 -23 -89 -3 -87 81 -35 0 7 -123 -71 106 8 -31 -96 -12 -49 -70 120 115 -116 47 114 30 6 75 -120 78 117 78
verify:true
Process finished with exit code 0

程序打包下载地址:

https://github.com/fengfanchen/Java/tree/master/SM2Demo

Java笔记-SM2(国密2)的调用及SM2、SM3、SM4使用场景相关推荐

  1. sm2 java 开源_SM2 国密算法被 Linux 内核社区接受

    原标题:SM2 国密算法被 Linux 内核社区接受 来自公众号: OSC开源社区 10 月 25 日,有开发者发文称,SM2 国密算法终于被 Linux 内核社区接受了.该作者表示,SM2 的补丁已 ...

  2. 【转】C#实现SM2国密加密

    本文主要讲解"国密加密算法"SM系列之SM2的C#实现方法,加密规则请详阅国密局发布的文档. 首先需第三方Nuget包:Portable.BouncyCastle (源码来自htt ...

  3. SM2 国密算法被 Linux 内核社区接受

    喜欢就关注我们吧! 10 月 25 日,有开发者发文称,SM2 国密算法终于被 Linux 内核社区接受了.该作者表示,SM2 的补丁已经更新到了 v7 版本,这个版本的补丁最终被社区接受,目前已经合 ...

  4. 技术分享 | 使用 mPaaS 配置 SM2 国密加密指南

    简介:随着移动智能终端的广泛应用,敏感信息极易被监控或盗取,给国家.企事业及个人带来极大政治.经济损失.金融和重要领域的各个企业正在逐步落实并完成国产密码改造工作.为解决客户侧因更换加密算法造成的种种 ...

  5. SM2国密算法加解密

    接口安全设计原则的一个点就是数据不能明文传输,除了https这个必须的请求外,接口数据加密也是一个重要的方式,下面介绍一下SM2国密算法加解密的使用方式. 这里我就针对目前前后端分离架构的方式来简单介 ...

  6. js 使用sm2 国密加密

    js 使用sm2 国密加密 由于项目中要对数据进行国密加密 注意: 同一个明文,加密后的密文都不同,解密的话要用私钥解密 js用sm2加密,首先要从后端获取公钥,用公钥加密 参考资料 crypto-j ...

  7. 国密算法分类总结:sm2,sm3,sm4等

    前面几篇博文对sm2,sm3,sm4,rsa,des等算法进行了介绍,并且用java,python语言实现了相关算法的运用. 本篇,作为一个阶段性总结,从整体上来回顾一下密码相关业务.当然,重点还是要 ...

  8. 记自己发现的—SM2国密算法应用的高危漏洞—CVE-2021-3711

    openssl在8月24日发布了openssl 1.1.1l的稳定版,其中修复了一个高危漏洞:CVE-2021-3711.该漏洞会影响openssl 1.1.1l 之前的所有包含SM2商密算法版本,其 ...

  9. SM2国密算法公钥解压缩

    SM2一般用到的或者第三方提供的公钥都是压缩过的,长度为66个长度,既33字节. 格式如下,保密期间秘钥内容用*代替了,从02到....3F3B共33字节.66个长度 06:028736002931F ...

  10. 【国密】利用gmssl生成SM2证书nginx访问

    之前我们项目的证书都是rsa的,这次本意是希望能升级到国密,但是理想过于丰满 一.GMSSL安装 # 下载 wget https://github.com/guanzhi/GmSSL/archive/ ...

最新文章

  1. json对象转为url参数_Day48_Ajaxamp;Json
  2. 解决Yum下载慢 的问题
  3. matlab程序的幂法,数值分析课程设计+幂法与反幂法MATLAB
  4. 删除二叉搜索树中的节点
  5. T-SQL | 逻辑查询处理内幕学习
  6. rabbitmq 延迟队列_Delayed Message 插件实现 RabbitMQ 延迟队列
  7. php如何打印程序运行时间,php计算程序运行时间的简单实例 - microtime
  8. php遍历文件夹(获得文件名)
  9. [转载]《博客园精华集》WebService筛选结果(共79篇)
  10. 如何配置RadASM
  11. (Spring+SpringMVC+mybatis)SSM企业职工工资管理系统
  12. android:模仿微信联系人效果
  13. 几何学五大公理_高中数学几何公理,定理。全部
  14. C#WebApi下载文件
  15. 摩斯密码php,普及一下LOL中的摩斯密码 绝对的干货
  16. DirectShow编程(1)- DirectShow介绍
  17. eclipse怎么调字体
  18. Windows 如何配置 scratch 3.0 GUI
  19. JAVAWEB学习笔记--Day3
  20. 越狱Season 1-Episode 20: Tonight

热门文章

  1. 进程和线程:进程的实现
  2. 互联网公司校招Java面试题总结及答案——阿里、腾讯
  3. IDEA方法注释模板
  4. 信息服务器v6,国内ipv6服务器
  5. 1u服务器怎么光驱重装系统,光盘重装系统步骤 光盘重装系统怎么做
  6. 唉,又一款老牌的代码编辑器,停止维护了...
  7. 开挂了! 9 岁神童即将大学毕业,开发出微型芯片
  8. Spring Cloud Alibaba 实战(五)Zuul篇
  9. java字符串替换星号_把字符串替换成星号
  10. 如何解决ubuntu16.04下载网速慢的问题