# SM2密码算法 JAVA 调用Demo
[TOC]
## Before Start
SM2算法使用请参考:[《GMT 0009-2012 SM2密码算法使用规范 》](http://www.gmbz.org.cn/main/viewfile/2018011001400692565.html)
---
在`bouncycastle` - `1.57`版本之后,加入了对 我国的**SM2、SM3、SM4算法的支持**。
[Bouncycastle releasenotes](https://www.bouncycastle.org/releasenotes.html)
![BC版本日志](https://img-blog.csdnimg.cn/20181220102556126.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ExMDA5MDIwMDk2,size_16,color_FFFFFF,t_70)
### Build with Maven
[适配JDK 1.5 版本](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on/1.60)
```xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
```
## QuickStart
### 密钥对生成
SM2 非对称算法密钥对生成。
```java
// 获取SM2椭圆曲线的参数
final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
// 获取一个椭圆曲线类型的密钥对生成器
final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
// 使用SM2参数初始化生成器
kpg.initialize(sm2Spec);
// 使用SM2的算法区域初始化密钥生成器
kpg.initialize(sm2Spec, new SecureRandom());
// 获取密钥对
KeyPair keyPair = kpg.generateKeyPair();
```
关于椭圆曲线的推荐参数请参考 [IETF draft-shen-sm2-ecdsa-02 #appendix-D](https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02#appendix-D)
> 在BC中已经为构造了SM2算法参数,并提供算法OID,请参考:<br>
> [国密算法OID及意义 ](http://gmssl.org/docs/oid.html)<br>
> [国密算法OID 源码](https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/asn1/gm/GMObjectIdentifiers.java)<br>
> [SM2算法推荐参数 源码](https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/asn1/gm/GMNamedCurves.java)
### 签名验签
产生了密钥对之后,就可以使用JAVA security 提供的一些标准化的接口来完成签名验签操作。
```java
/*
获取公私钥
*/
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 生成SM2sign with sm3 签名验签算法实例
Signature signature = Signature.getInstance(
GMObjectIdentifiers.sm2sign_with_sm3.toString()
, new BouncyCastleProvider());
/*
签名
*/
// 签名需要使用私钥,使用私钥 初始化签名实例
signature.initSign(privateKey);
// 签名原文
byte[] plainText = "Hello world".getBytes(StandardCharsets.UTF_8);
// 写入签名原文到算法中
signature.update(plainText);
// 计算签名值
byte[] signatureValue = signature.sign();
System.out.println("signature: \n" + Hex.toHexString(signatureValue));
/*
验签
*/
// 签名需要使用公钥,使用公钥 初始化签名实例
signature.initVerify(publicKey);
// 写入待验签的签名原文到算法中
signature.update(plainText);
// 验签
System.out.println("Signature verify result: " + signature.verify(signatureValue));
```
> 你可以在 [国密算法OID ](http://gmssl.org/docs/oid.html)中找到需要算法的OID字符串。
> 如: SM2Sign-with-SM3 `1.2.156.10197.1.501`
---
# JAVA SM2 数字证书生成Demo
## Before Start
X.509数字证书请参考:
[RFC5280 Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile](https://tools.ietf.org/html/rfc5280)
中文版的简要介绍可以参考这篇文章 [Agzs . X509证书--ANS1结构](https://blog.csdn.net/code_segment/article/details/77163652)
如果还未能**生成SM2密钥对**请先阅读
- [JAVA SM2 密钥生成 签名验签](https://blog.csdn.net/q1009020096/article/details/85115698)
### Build with Maven
- [bcprov](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on/1.60)
- [bcpkix](https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on)
```xml
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.60</version>
</dependency>
```
## QuickStart
[Github](https://github.com/Trisia/alg-sm2-demo)
```java
/**
* BouncyCastle算法提供者
*/
private static final Provider BC = new BouncyCastleProvider();
```
### 生成自签名公私钥对
`keyPairGenerator`的构造请参考 [JAVA SM2 密钥生成 签名验签](https://blog.csdn.net/q1009020096/article/details/85115698)
```java
// 产生密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
```
### 证书签名算法算法提供者
在制作证书时需要使用到签名算法签名证书中部分数据区域,国密类型的数字证书使用的签名算法是`SM3withSM2`,这里使用私钥创建算法提供容器。
```java
ContentSigner sigGen = new JcaContentSignerBuilder("SM3withSM2")
.setProvider(BC)
.build(keyPair.getPrivate());
```
### 设置证书信息
设置证书的基本数据:使用者信息、颁发者信息、证书序号、证书生效日期、证书失效日期,以及证书扩展属性。
#### 标识信息构造(DN)
上面提到的使用者信息、颁发者信息,使用Distinct Name的方式来描述。
关于DN中的各个字段的含义请参考 [IBM Previous Next
Distinguished Names](https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.5.0/com.ibm.mq.sec.doc/q009860_.htm)
实际上简单来讲就是,用来确定“实体” 身份/信息 的一系列**列键值对**组成的字符串。
这里的键是一个`ASN1ObjectIdentifier`,实际上Bouncycastle已经为我们把需要的大多键都已经列好了,我们只要使用这个类`org.bouncycastle.asn1.x500.style.BCStyle`的静态变量就可以。
```java
private static X500NameBuilder createStdBuilder() {
X500NameBuilder builder = new X500NameBuilder(BCStyle.INSTANCE);
// 国家代码
builder.addRDN(BCStyle.C, "CN");
// 组织
builder.addRDN(BCStyle.O, "HZNU");
// 省份
builder.addRDN(BCStyle.ST, "Zhejiang");
// 地区
builder.addRDN(BCStyle.L, "Hangzhou");
return builder;
}
```
然后我们就可以使用`X500NameBuilder`的`build()`方法构造对应的DN了。
> [BCStyle 源码请参考](https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/asn1/x500/style/BCStyle.java),也可以使用与该文件中处于同级目录的[RFC4519Style](https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/asn1/x500/style/RFC4519Style.java)
#### 获取扩展密钥用途构造(可选)
如果需要设置证书的扩展密钥用途,可以使用`DERSequence`来构造一个拓展密钥用途的序列。
[拓展密钥用途](https://tools.ietf.org/html/rfc5280#section-4.2.1.12)
```java
public static DERSequence extendedKeyUsage() {
// 构造容器对象
ASN1EncodableVector vector = new ASN1EncodableVector();
// 客户端身份认证
vector.add(KeyPurposeId.id_kp_clientAuth);
// 安全电子邮件
vector.add(KeyPurposeId.id_kp_emailProtection);
return new DERSequence(vector);
}
```
> 扩展密钥用途的各个OID Bouncycastle 已经为我们提供,请参考[KeyPurposeId](https://github.com/bcgit/bc-java/blob/master/core/src/main/java/org/bouncycastle/asn1/x509/KeyPurposeId.java)
#### 证书信息构造
接下来可以使用`X509v3CertificateBuilder` 来设置证书的基本参数,下面列举基本一些证书参数和扩展参数的设置方式。
```java
// 构造X.509 第3版的证书构建者
X509v3CertificateBuilder certGen = new JcaX509v3CertificateBuilder(
// 颁发者信息
createStdBuilder().build()
// 证书序列号
, BigInteger.valueOf(1)
// 证书生效日期
, new Date(Syste
没有合适的资源?快使用搜索试试~ 我知道了~
SM2密码算法 JAVA 调用演示程序。.zip
共21个文件
java:16个
txt:2个
xml:1个
需积分: 5 0 下载量 192 浏览量
2024-01-13
21:41:54
上传
评论
收藏 33KB ZIP 举报
温馨提示
Java是一种高性能、跨平台的面向对象编程语言。它由Sun Microsystems(现在是Oracle Corporation)的James Gosling等人在1995年推出,被设计为一种简单、健壮、可移植、多线程、动态的语言。Java的主要特点和优势包括以下几个方面: 跨平台性(Write Once, Run Anywhere): Java的代码可以在不同的平台上运行,只需编写一次代码,就可以在任何支持Java的设备上执行。这得益于Java虚拟机(JVM),它充当了代码和底层硬件之间的中介。 面向对象: Java是一种纯粹的面向对象编程语言,支持封装、继承和多态等面向对象的概念。这使得Java编写的代码更加模块化、可维护和可扩展。 多线程支持: Java内置了对多线程的支持,允许程序同时执行多个任务。这对于开发需要高并发性能的应用程序(如服务器端应用、网络应用等)非常重要。 自动内存管理(垃圾回收): Java具有自动内存管理机制,通过垃圾回收器自动回收不再使用的对象,使得开发者不需要手动管理内存,减轻了程序员的负担,同时也减少了内存泄漏的风险。
资源推荐
资源详情
资源评论
收起资源包目录
SM2密码算法 JAVA 调用演示程序。.zip (21个子文件)
the-code
pom.xml 1KB
src
test
resources
PubKey.txt 124B
PrvKey.txt 200B
main
java
edu
hznu
crypto
algsm2demo
SM2PKCS10Tools.java 4KB
SM2Support.java 9KB
SM2CARootKeyStoreDemo.java 5KB
SM2SubCertGenerateDemo.java 6KB
ConstructSm2PubKeyDemo.java 1KB
CertParser.java 3KB
SM2CertDemo.java 6KB
HmacSm3Demo.java 2KB
RSAKeyGenDemo.java 3KB
SM2KeyPairInjectDemo.java 3KB
AlgSm2Demo.java 3KB
SM2KeyGenerateFactory.java 2KB
sm4
Sm4Mode.java 538B
TestSm4.java 3KB
Sm4.java 14KB
SM2KeyStoreUseDemo.java 4KB
.gitignore 270B
README.md 12KB
共 21 条
- 1
资源评论
JJJ69
- 粉丝: 6352
- 资源: 5918
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功