完整的认识GmSSL和(WIN+Linux)安装编译的操作流程

国密算法简述

关于GmSSL

        GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法、SM2国密数字证书及基于SM2证书的SSL/TLS安全通信协议,支持国密硬件密码设备,提供符合国密规范的编程接口与命令行工具,可以用于构建PKI/CA、安全通信、数据加密等符合国密标准的安全应用。GmSSL项目是OpenSSL项目的分支,并与OpenSSL保持接口兼容。因此GmSSL可以替代应用中的OpenSSL组件,并使应用自动具备基于国密的安全能力。

        GmSSL是支持国密算法和标准的OpenSSL分支,也就是说GmSSL是在OpenSSL代码基础上添加的国密算法。因此为了兼容OpenSSL,GmSSL编译后生成的so文件名称与OpenSSL一致,都是libcrypto.so,因此在编译安装GmSSL版本的时候,如果GmSSL版本与OpenSSL版本不一致,可能会存在的与openSSL版本冲突的问题。

最简单直接的方法就是:将GmSSL编译成静态函数库。

关键特性

  • 支持SM2/SM3/SM4/SM9/ZUC等全部已公开国密算法
  • 支持国密SM2双证书SSL套件和国密SM9标识密码套件
  • 高效实现在主流处理器上可完成4.5万次SM2签名
  • 支持动态接入具备SKF/SDF接口的硬件密码模块
  • 支持门限签名、秘密共享和白盒密码等高级安全特性
  • 支持JavaGoPHP等多语言接口绑定和REST服务接口

密码算法

        国密算法是国家商用密码算法的简称。自2012年以来,国家密码管理局以《中华人民共和国密码行业标准》的方式,陆续公布了SM2/SM3/SM4等密码算法标准及其应用规范。其中“SM”代表“商密”,即用于商用的、不涉及国家秘密的密码技术。其中SM2为基于椭圆曲线密码的公钥密码算法标准,包含数字签名、密钥交换和公钥加密,用于替换RSA/Diffie-Hellman/ECDSA/ECDH等国际算法;SM3为密码哈希算法,用于替代MD5/SHA-1/SHA-256等国际算法;SM4为分组密码,用于替代DES/AES等国际算法;SM9为基于身份的密码算法,可以替代基于数字证书的PKI/CA体系。通过部署国密算法,可以降低由弱密码和错误实现带来的安全风险和部署PKI/CA带来的开销。

 以上内容摘抄自GmSSL官网:http://gmssl.org/

(Linux+Win)平台安装编译GmSSL(JAVA模块)

使用前介绍

        本文主要介绍Linux和Win下关于Java模块的编译安装,使用GmSSL主要是通过编译生成可执行的函数库,加载函数库来执行,一般分为动态函数库和静态函数库,动态函数库会比较依赖系统环境,开始之前先了解一下动态函数库的文件,也就是.dll/.so文件,我们知道用C/C++编写的程序如果用于Win平台则编译为.dll(dynamic link library)文件,Linux平台则编译为libxxx.so(shared object)文件。

        这里在加载调用函数库就得用到JNA/JNI;

JNA简单介绍

        先理解一下JNI(Java Native Interface),对于不同语言间的通信,JNI可以允许Java代码和其他语言之间(尤其是C/C++)代码进行交互,在遵守调用约定的前提下,JNI调用C/C++的过程中如下,步骤过多,首先得使用C语言编写一个.dll/.so共享库,

使用SUN规定的数据结构替代C语言的数据结构,调用已有的 dll/so中公布的函 数。然后再在Java中载入这个库dll/so,最后编写Java native函数作为链接库中函数的代理。经过这些繁琐的步骤才能在Java中调用 本地代码。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

        而JNA(Java Native Access)是一个开源框架,是建立在经典的JNI基础之上的一个框架。JNA大大简化了调用本地方法的过程,使用很方便,基本上不需要脱离Java环境就可以完成。

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_15,color_FFFFFF,t_70,g_se,x_16


Linux下安装编译

        GmSSL的使用需要下载gmssl,解压后通过make(windows上位nmake)编译,安装后才能使用,Linux和Mac上的编译安装可以按照官网平台上的指引进行编译安装,而Windows上的则需要启用相对应的win配置文件(针对于JAVA)使用的编译安装;

        关于GmSSL,是会比较依赖于内部函数库环境,但编译成静态库会减少对函数库环境的依赖;

按照官方文档在Mac上编译安装java模块的函数库,但是Linux按照官网的步骤执行java编译就会失败,因为目前GmSSL还不能实现在所有的操作系统上自动编译java接口代码,因此编译脚本中默认没有开启Java接口的编译,官网地址:http://gmssl.org/;

 

    Mac开启Java脚本接口编译,可以在源代码的根目录下找到Configure,找到“$config{dirs} = [ "crypto", "ssl", "engines", "apps", "util", "tools", "fuzz", "test" ];”,

    将其改为“$config{dirs} = [ "crypto", "ssl", "engines", "apps", "util", "tools", "fuzz", "test", "java" ];”。

    重新通过命令编译安装即可(只适合Mac)

        在linux上,编译安装不需要在Configure配置文件上配置"java";

1、下载GmSSL环境包

        通过GitHub平台下载GmSSL环境包,GmSSL下载,也可以在这里下载GmSSL下载,下载后将其上传到linux服务器上,并进行解压;

unzip GmSSL-master.zip

2、解压,配置安装信息

        将GmSSL解压后,进入目录,保持Configure文件中$config{dirs}原来的设置,不要添加java目录,完成make install,会在GmSSL目录内得到libcrypto.so;

进入解压后的GmSSL包内,配置安装路径,编译为静态库:./config --prefix=/usr/local/gmssl --openssldir=/usr/local/gmssl no-shared,–prefix表示安装路径;no-shared 表示只编译静态库;默认生成64位库。

make install 命令需要管理员权限才能运行,不然会报错, 无权限对该路径进行写入;

进入解压后的目录

加载配置,编译安装,make install需要管理员权限才能运行;

./config
make
sudo make install

安装完成后可以通过执行gmssl命令行工具检查是否安装成功

$ gmssl version

GmSSL 2.0 - OpenSSL 1.1.0d

可能会遇到的问题看以下解决方案

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_12,color_FFFFFF,t_70,g_se,x_16

执行make install后GmSSL根目录下发现`libcrypto.so`,`libcrypto.so.1.1`

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

3、编译java模块函数库

        编译java模块的函数库,如果按照官网正常去执行make install在生成函数库时会出错,进入java目录,通过查看目录下build.sh内容如下;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

GmSSL默认安装目录是/usr/local

         根据build.sh的内容,我们可以通过执行gcc命令来生成动态函数库,libgmssljni.so;

        这里注意的是:"/home/gmssl/GmSSL":就是解压GmSSL的根目录(注意别被误导)

gcc -shared -fPIC -Wall -I./jni -I /home/gmssl/GmSSL/include -L /home/gmssl/GmSSL GmSSL.c -lcrypto -o libgmssljni.so

4、测试运行GmSSL.java

        将解压目录下的(libcrypto.so,libcrypto.so.1.1)/libcrypto.a文件拷贝到java目录下,java目录下要有这三个文件;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

编译运行测试GmSSL.java文件

mp GmSSL-master GmSSL

mkdir -p org/gmssl

cp GmSSL.java org/gmssl

javac org/gmssl/GmSSL.java

java -Djava.library.path=/home/gmssl/GmSSL/java -classpath /home/gmssl/GmSSL/java org.gmssl.GmSSL

        特别注意的是:GmSSL需要放在org/gmssl中,进行编译运行,这是因为需要保证java文件中GmSSL的package为org.gmssl,这是因为将生成动态库.so文件反编译会发现里面是写死的路径;

        所以目前只能放置在org/gmssl中去编译GmSSL.java;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

 

得到正确的运行结果。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

 在Linux下编译运行成功;

可能会遇到的问题:

在安装编译后通过gmssl查看版本号提示:

“gmssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory”

查找一下libssl.so.1.1的位置,然后连接到/usr/lib64/libssl.so.1.1即可,以下操作
 


[root@localhost ~]# find / -name libssl.so.1.1
/usr/local/lib64/libssl.so.1.1

[root@localhost ~]# ln -s /usr/local/lib64/libssl.so.1.1  /usr/lib64/libssl.so.1.1

[root@localhost ~]# ln -s /usr/local/lib64/libcrypto.so.1.1  /usr/lib64/libcrypto.so.1.1

[root@localhost ~]# gmsslssl version
GmSSL 2.5.3 - OpenSSL 1.1.0d  28 Aug 2019

 

Gmssl与openSSL冲突:

可以在加载配置文件的时候指定gmssl的安装编译路径(默认在usr/local)

./config --prefix=/usr/local/gmssl --openssldir=/usr/local/gmssl no-shared

“no-shared”:是关键,只生成静态库.a;

配置静态库也可以通过指定no-shared;

需要生成静态库通过shared指定;


Win下安装编译

        Win在编译安装GmSSL之前需要先安装VS2017,安装ActivePerl,安装NASM,三个安装环境安装包可以通过下载:Windows安装GmSSL需要的安装环境-其它文档类资源-CSDN下载

        安装环境在WIN10环境,也在WIN11环境实操过;

1、编译工具安装准备

1.1 安装VS2017

主要使用它的编译器,若已安装,则跳过。

        首先我们下载好VS2017安装引导程序后,里面包含如下四个文件,

503f3c09ff4048c4942761d6bc0f3446.png

vs_Community.exe:社区版,免费。但是需要登录微软账号,否则30天后过期,不能继续使用。

vs_Enterprise.exe:企业版,需要注册码。

vs_Professional.exe:专业版,需要注册码。

vs_TestProfessional.exe:测试专业版。

        启动vs_Community.exe,我们只需要C++功能,所以选择“工作负荷”下的“使用C++的桌面开发”,如下;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

        然后往下拉,选择“Visual Studio 扩展开发”; 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

        注意:未勾选此项时,VS不能安装插件*.vsix,如QT插件qt-vsaddin-msvc2017-2.4.3-rev.07.vsix,

        现象是双击*.vsix安装,没有任何反应。

         然后在“单个组件”中选择“用于x86和x64的Visual C++ MFC”,不然不能创建基于MFC的工程。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

另外“安装位置”可全部设置到你指定的盘,我这里在H盘,避免过大占用C盘;

为确保“位置”处显示为“H:\”开头,可以在“语言包”、“安装位置”几个标签多点击切换试试。

然后选择右下角“全部下载后再安装”,点击“安装”,如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

 下载完成会自动开始安装

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

安装完成后,使用在微软官网注册的账号登录即可,实现免费使用。

        需要注意的是,安装完成后,下载缓存的文件夹,我这里是“H:\VS2017\Packages”目录,这个说是下载缓存,但是千万别删,否则无法创建工程。

1.2 安装ActivePerl

        64位ActivePerl-5.26,解压后执行可执行文件,进行安装,安装类型选择“Typical”,其他默认,最后一步安装时间较长。

6cbebb49cc164a198540350be834b653.png

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_18,color_FFFFFF,t_70,g_se,x_16

在cmd中,输入命令查看perl版本号。

perl -v

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

 表明安装成功。

1.3 安装NASM

以管理员身份运行nasm-2.15.05-installer-x64.exe,进行默认安装即可。

并将NASM安装目录添加至Windows系统环境变量Path中。

1640bd3785224ee794fd3ebbe9fc21d3.png

b6a0f3e257c54ccca93bf71ee0ef7c35.png

至此,所需要的环境已经安装完成了; 

2、解压GmSSL源码

管理员权限,打开VS Tools中“适用于VS 2017 的x64 本机工具命令提示”。

进入GmSSL解压目录,配置生成64位的库

如果想生成32位的,则perl Configure VC-WIN32

perl Configure VC-WIN64A

3、Win下编译安装GmSSL

 

然后执行编译:

nmake

若报错,参考以下解决编译报错。
直到编译成功后继续。

编译过程可能会提示错误,无法解析外部符号 EVP_get_ciphernames;无法解析的外部符号 EVP_get_digestnames,原因是因为EVP_get_ciphernamesEVP_get_digestnames这2个函数位于GmSSL-master\include\openssl\evp.h,似乎是没找到这2个函数的实现。

在GmSSL的github仓库中,在GmSSL/crypto/evp/names2.c文件中,历史版本有这2个函数的实现,新版本不知道什么原因,这2个函数实现被删除了。

因此这里将names2.c文件的历史版本中,将函数实现拷贝出来,追加到新names2.c文件末尾,再重新编译就好了。

下面有具体代码

安装

安装GmSSL,执行nmake install;

nmake install

命令编译安装成功后,在环境变量中配置gmssl的环境,测试gmssl -version输出版本号

gmssl version

        若前面不是以管理员权限运行,“适用于VS 2017 的x64 本机工具命令提示”,则此处会报错。

GmSSL默认安装路径为C:\Program Files\GmSSL;

        安装完成后,将GmSSL命令行工具路径C:\Program Files\GmSSL\bin,添加到环境变量中。

在cmd中,输入命令查看GmSSL版本。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_11,color_FFFFFF,t_70,g_se,x_16

安装成功; 

4、安装GmSSL下java模块动态函数库

        GmSSL在Windows上编译安装生成java函数库,并不像在Linux系统上通过gcc可以生成,GmSSL源码中存在makefile文件,这个文件是用于对GmSSL进行编译安装的配置的,在进入/java目录下可以看到有一个winmake的文件,这个就是java模块在Windows系统下的makefile文件,因此需要通过winmake配置文件执行nmake install才能成功编译;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_7,color_FFFFFF,t_70,g_se,x_16

进入/java目录下 执行nmake -f winmake,编译成功后会在目录下找到gmssljni.dll函数库

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

 

GmSSL在编译过程中可能会遇到的异常:crypto\aes\aes_cfb.obj : fatal error LNK1112: 模块计算机类型“x86”与目标计算机类型“x64”冲突,该异常是因为执行nmake命令需要用VS Tools的命令行工具,不是本机自带的cmd

5、测试运行

        跟linux测试一样,新建org/gmssl,将GmSSL.java放到目录下,编译后,通过指定lib配置信息执行GmSSL.class文件测试函数库是否使用正常.

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

成功; 

可能报错如下:

libcrypto-1_1-x64.def : error LNK2001: 无法解析的外部符号 EVP_get_ciphernames
libcrypto-1_1-x64.def : error LNK2001: 无法解析的外部符号 EVP_get_digestnames
libcrypto.lib : fatal error LNK1120: 2 个无法解析的外部命令
NMAKE : fatal error U1077: “link”: 返回代码“0x1”

原因:

EVP_get_ciphernames、EVP_get_digestnames这2个函数位于GmSSL-master\include\openssl\evp.h,似乎是没找到这2个函数的实现。

解决办法:

在GmSSL的github仓库中,在GmSSL-master/crypto/evp/names2.c文件中,历史版本有这2个函数的实现,新版本不知道什么原因,这2个函数实现被删除了。

所以,我们只需要从names2.c文件的历史版本中,将函数实现拷贝出来,追加到新names2.c文件末尾,再次重新编译即可。

具体解决步骤:

这里将需要拷贝的代码,列出来,如下:

static void cipher_name_len(const EVP_CIPHER *cipher, const char *from,
	const char *to, void *x)
{
	*((int *)x) += strlen(EVP_CIPHER_name(cipher));
}

static void cipher_name(const EVP_CIPHER *cipher, const char *from,
	const char *to, void *x)
{
	strcat((char *)x, EVP_CIPHER_name(cipher));
}

char *EVP_get_ciphernames(int aliases)
{
	char *ret = NULL;
	int len = 0;
	EVP_CIPHER_do_all_sorted(cipher_name_len, &len);

	ret = OPENSSL_zalloc(len);
	if (!ret) {
		return NULL;
	}

	EVP_CIPHER_do_all_sorted(cipher_name, ret);
	return ret;
}

char *EVP_get_digestnames(int aliases)
{
	return "sm3:sha1:sha256";
}

首先将上述4个函数,追加至names2.c文件末尾。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

然后执行一下清除

nmake clean

再执行编译

nmake

可以编译通过了。

在win下编译报这2个函数未实现,但是后来在Linux下编译,在没有改代码的前提下,居然可以直接编译通过,看来这个与平台还有关系。官网也只是有提到不兼容每个系统之类的.

SpringBoot整合GmSSL

SpringBoot整合,只需要将GmSSL.java文件引入SpingBoot工程中,当然还是得保证GmSSL的package oeg.gmssl,因此这一项工程的路径应该得为org/gmssl,这里贴一下C文件中实现的部分代码;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAU2luZGVyX-Wwj-W-tw==,size_20,color_FFFFFF,t_70,g_se,x_16

 


至此,整个关于国密GmSSL在Linux系统和Win系统的安装和部署教程已经完结,根据GmSSL具体服务的工程后面再发布到在线网站中测试使用;

END.

 

 

 

 

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sinder_小德

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值