# GmSSL-Java
## 简介
本项目是GmSSL密码库的Java语言封装,可以用于Java环境和Android系统上的应用开发。GmSSL-Java目前提供了随机数生成器、SM3哈希、SM3消息认证码(HMAC-SM3)、SM4加密(包括分组加密和CBC/CTR/GCM加密模式)、ZUC加密、SM2加密/签名、SM9加密/签名、SM2证书解析等功能,可以覆盖目前国密算法主要应用开发场景。
GmSSL-Java是采用JNI (Java Native Interface)方式实现的,也就是说所有底层密码功能(以及消息、文件的编解码等)均为调用GmSSL库实现,因此在功能、标准、性能上和GmSSL的C库、命令行工具几乎完全一致。GmSSL-Java将各种算法封装为独立的Java类,方便应用调用。包含的具体类及功能参见接口说明一节。
因为GmSSL-Java以JNI方式实现,GmSSL-Java不仅包含Java语言实现的Java类库(Jar包),还包括C语言实现的本地库(libgmssljni动态库),其中libgmssljni这个本地库是Java接口类库和GmSSL库(libgmssl)之间的胶水层,应用部署时还需要保证系统中已经安全了GmSSL库。虽然看起来这种实现方式比纯Java实现的类似更麻烦,而且因为包含C编译的本地代码,这个类库也失去了Java代码一次编译到处运行的跨平台能力,但是这是密码库的主流实现方式。相对于纯Java实现来说,GmSSL-Java可以充分利用成熟和功能丰富的GmSSL库,在性能、标准兼容性上都更有优势,并且可以随着GmSSL主项目的升级获得功能和性能上的升级。
## 下载
* GmSSL-Java主分支源代码 [GmSSL-Java-main.zip](https://github.com/GmSSL/GmSSL-Java/archive/refs/heads/main.zip) (版本号:2.1.0 dev)
* 依赖的GmSSL库主分支源代码 [GmSSL-master.zip](https://github.com/guanzhi/GmSSL/archive/refs/heads/master.zip) (版本号:3.1.1 Dev)]
* GitHub主页:https://github.com/GmSSL/GmSSL-Java
## 项目构成
GmSSL的项目组成主要包括C语言的本地代码、`src`目录下的Java类库代码、`examples`目录下面的例子代码。其中只有本地代码和`src`下面的Java类库代码会参与默认的编译,生成动态库和Jar包,而`examples`下的例子默认不编译也不进入Jar包。
GmSSL-Java提供一个包`org.gmssl`,其中包含如下密码算法类
* org.gmssl.Random
* org.gmssl.Sm3
* org.gmssl.Sm3Hmac
* org.gmssl.Sm3Pbkdf2
* org.gmssl.Sm4
* org.gmssl.Sm4Gcm
* org.gmssl.Sm4Cbc
* org.gmssl.Sm4Ctr
* org.gmssl.Zuc
* org.gmssl.Sm2Key
* org.gmssl.Sm2Signature
* org.gmssl.Sm2Certificate
* org.gmssl.Sm9EncMasterKey
* org.gmssl.Sm9EncKey
* org.gmssl.Sm9SignMasterKey
* org.gmssl.Sm9SignKey
* org.gmssl.Sm9Signature
* org.gmssl.GmSSLException
其中还有一个特殊的`org.gmssl.GmSSLJNI`类,这是底层的JNI封装,不建议用户调用。
## 开发者
<a href="https://github.com/GmSSL/GmSSL-Java/graphs/contributors">
<img src="https://contrib.rocks/image?repo=GmSSL/GmSSL-Java" />
</a>
## 编译和安装
GmSSL-Java依赖GmSSL项目,在编译前需要先在系统上编译、安装并测试通过GmSSL库及工具。请在https://github.com/guanzhi/GmSSL 项目上下载最新的GmSSL代码,并完成编译、测试和安装。
首先下载最新的GmSSL-Java代码,然后安装编译工具链。
GmSSL-Java的当前版本采用CMake编译工具链,需要在系统上安装基础的GCC编译工具链、CMake和Java环境,在Ubuntu/Debian系统上可以执行如下命令安装依赖的工具。
```bash
sudo apt update
sudo apt install build-essential cmake default-jdk
```
安装完成后可以通过CMake编译
```bash
mkdir build
cd build
cmake ..
make
make test
```
编译并测试成功后可以显示
```bash
$ make test
Running tests...
Test project /path/to/GmSSL-Java/build
Start 1: main
1/1 Test #1: main ............................. Passed 2.27 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 2.27 sec
```
此时查看`build`目录下可以看到生成的本地动态库`libgmssljni`和GmSSLJNI的Jar包`GmSSLJNI.jar`、`GmSSLJNI-2.1.0-dev.jar`。
## 开发手册
### 随机数生成器
类`Random`实现随机数生成功能,通过`randBytes`方法生成的是具备密码安全性的随机数,可以用于密钥、IV或者其他随机数生成器的随机种子。
```java
public class Random {
public Random();
public byte[] randBytes(int len);
public void randBytes(byte[] out, int offset, int len);
}
```
`Random`是通过调用操作系统的密码随机数生成器(如`/dev/urandom`)实现的。由于底层操作系统的限制,在一次调用`randBytes`时不要指定明显超过密钥长度的输出长度,例如参数`len`的值不要超过128,否则可能导致阻塞,或者产生错误和异常。如果应用需要大量的随机数据,不应使用`Random`,而是应该考虑其他伪随机数生成算法。
需要注意的是,`Random`类的安全性依赖于底层的操作系统随机数生成器的安全性。在服务器、笔记本等主流硬件和Windows、Linux、Mac主流服务器、桌面操作系统环境上,当计算机已经启动并且经过一段时间的用户交互和网络通信后,`randBytes`可以输出高质量的随机数。但是在缺乏用户交互和网络通信的嵌入式设备中,`randBytes`返回的随机数可能存在随机性不足的问题,在这些特殊的环境中,开发者需要提前或在运行时检测`Random`是否能够提供具有充分的随机性。
### SM3哈希
SM3密码杂凑函数可以将任意长度的输入数据计算为固定32字节长度的哈希值。
类`Sm3`实现了SM3的功能。
```java
public class Sm3 {
public final static int DIGEST_SIZE = 32;
public Sm3();
public void reset();
public void update(byte[] data, int offset, int len);
public void update(byte[] data);
public byte[] digest();
}
```
下面的例子展示了如何通过类`Sm3`计算字符串的SM3哈希值。
```java
import org.gmssl.Sm3;
public class Sm3Example {
public static void main(String[] args) {
Sm3 sm3 = new Sm3();
sm3.update("abc".getBytes());
byte[] dgst = sm3.digest();
int i;
System.out.printf("sm3('abc'): ");
for (i = 0; i < dgst.length; i++) {
System.out.printf("%02x", dgst[i]);
}
System.out.print("\n");
}
}
```
这个例子的源代码在`examples/Sm3Example.java`文件中,编译并运行这个例子。
```bash
$ javac -cp /path/to/jar/GmSSLJNI.jar Sm3Example.java
$ java -Djava.library.path=/path/to/dylib/ -cp /path/to/jar/GmSSLJNI.jar:. Sm3Example
sm3('abc'): 66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
```
打印出的`66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0`就是字符串`abc`的哈希值。字符串`abc`的哈希值也是SM3标准文本中给出的第一个测试数据,通过对比标准文本可以确定这个哈希值是正确的。
也可以通过`gmssl`命令行来验证`Sm3`类的计算是正确的。
```bash
$ echo -n abc | gmssl sm3
66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0
```
可以看到输出的结果是一样。
注意,如果将字符串`abc`写入到文本文件中,文本编辑器通常会在文本结尾处增加格外的结束符,如`0x0a`字符,那么计算出的哈希值将不是上面的结果,比如可能是`12d4e804e1fcfdc181ed383aa07ba76cc69d8aedcbb7742d6e28ff4fb7776c34`。如果命令`echo`不使用`-n`的参数,也会出现同样的错误。这是很多开发者在初次进行哈希函数开发时容易遇到的错误,哈希函数的安全性质保证,即使输入的消息只差一个比特,那么输出的哈希值也完全不同。
如果需要哈希的数据来自于网络或者文件,那么应用可能需要多次读取才能获得全部的数据。在通过`Sm3`计算哈希值时,应用不需要通过保存一个缓冲区来保存全部的数据,而是可以通过多次调用`update`方法,�

zhouhengying123
- 粉丝: 1
最新资源
- 混合高斯模型中期望最大算法的实现方法探讨
- 关于混合高斯模型的期望最大算法的实现
- 一款强大的大模型微调数据集生成和管理工具
- 使用LLaMA-Factory微调多模态大语言模型的示例代码 Demo of Finetuning Multimodal LLM with LLaMA-Factory
- 基于大语言模型 API 的外挂知识库问答系统(含 neo4j 知识图谱实现)
- 数据库课程设计研究报告学生成绩管理系统.doc
- 信息技术课中的生活算法之一-操作教学.docx
- 简析互联网时代高职教育新发展.docx
- 试论中职教师信息化教学创新的研究.docx
- ASP企业员工管理系统的方案设计书与实现.doc
- 东莞理工学院C语言程序设计方案作业实验二.docx
- 试论工程项目管理的科学化.docx
- 基于大语言模型API(本地或商用API)的外挂知识库问答系统(附neo4j实现知识图谱)
- 用大数据思维提升职业教育学生的双创能力.docx
- PLC控制运料小车的方案设计书1.doc
- 优质模板旅游管理电子商务毕业论文答辩演讲课件ppt模板.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


