GmSSL相遇
最近想要使用国密算法写一些工具,不知不觉遇到了GmSSL,先试试看。
1. 安装GmSSL
参考官网的快速上手,我的目标主机是没有管理员权限的Linux,故而编译源码安装到自己的目录下,下载源码。
$ unzip -q GmSSL-master.zip # -q 解压时不打印列表
$ cd GmSSL-master
$ mkdir -p ~/apps/GmSSL
$ ./config --prefix=/home/xflm/apps/GmSSL # 大约3s
$ make -j8 # 启用8个进程编译,根据实际主机的特点进行选择,大约2.5分钟
$ make install # 大约2.5分钟
$ cd ~/apps/GmSSL
$ ls
bin/ include/ lib/ share/ ssl/
简单总结一下这些文件:
文件 | 描述 |
---|---|
bin/gmssl | 这个文件即gmssl命令程序 |
include/openssl/ | 这个目录下是使用gmssl库会用到的头文件 |
lib/ | gmssl的动态库、静态库文件 |
share/ | 帮助文档 |
ssl/ | gmssl配置文件等 |
2. 命令行运行GmSSL
由于不是通过管理员安装到系统目录,故而./bin/gmssl
执行会失败,需要使用下面语句执行:
# GmSSL有自己的命令行
$ LD_LIBRARY_PATH=~/apps/GmSSL/lib ./bin/gmssl
GmSSL>q # q 退出
# 也可直接进行密码运算
$ echo -en "1" | LD_LIBRARY_PATH=~/apps/GmSSL/lib ./bin/gmssl sm3
(stdin)= cbddd......
若以后需要在命令行使用,在~/.bashrc
中添加一行:
alias gmssl='LD_LIBRARY_PATH=~/apps/GmSSL/lib ~/apps/GmSSL/bin/gmssl'
然后重新加载~/.bashrc
:
$ . ~/.bashrc
3. 脚本运行GmSSL
脚本中alias
行不通,执行LD_LIBRARY_PATH=~/apps/GmSSL/lib ~/apps/GmSSL/bin/gmssl
也不行,需要这样做:
gmssl.sh
#!/bin/bash export LD_LIBRARY_PATH=~/apps/GmSSL/lib # 必须导出LD_LIBRARY_PATH到环境变量,脚本运行在子bash中,不会污染当前bash环境 GMSSL=~/apps/GmSSL/bin/gmssl # 定义个变量,下面多次引用时就不用写这么长了 echo -en "$1" | $GMSSL sm3
执行:
$ chmod +x gmssl.sh
$ ./gmssl.sh 1
(stdin)= cbdddb......
4. C程序使用GmSSL
main.c
#include <stdio.h> #include "openssl/sm3.h" int main(int argc, char *argv) { (void)argc; (void)argv; sm3_ctx_t sm3[1]; uint8_t digest[32]; int i; sm3_init(sm3); sm3_update(sm3, (uint8_t *)"1", 1); sm3_final(sm3, digest); printf("SM3: "); for(i = 0; i < 32; i++) { printf("%02X", digest[i]); } puts(""); return 0; }
4.1 链接动态库
# 因为libcrypto.a和libcrypto.so在同一目录,gcc优先链接.so
# 链接动态库时,main.c的位置可以在-lcrypto之后
# 此处~表示用户目录,-I和~之间必须有空格,若~换成/home/xflm则可以没有空格
$ gcc -I ~/apps/GmSSL/include -L ~/apps/GmSSL/lib -lcrypto main.c
# 由于动态库不在系统搜索路径内,需要指定到LD_LIBRARY_PATH中
$ LD_LIBRARY_PATH=~/apps/GmSSL/lib ./a.out
SM3: CBDDDB......
# 可执行文件较小
$ du -bs a.out
7226 a.out
4.2 链接静态库
# 因为libcrypto.a和libcrypto.so在同一目录,需强制gcc链接静态库,注意此处写法
# 链接静态库时,main.c的位置必须在-l:libcrypto.a之前
$ gcc main.c -I/home/xflm/GmSSL/include -L/home/xflm/GmSSL/lib -l:libcrypto.a
# 直接指定静态库文件也是可以的,注意顺序
$ gcc main.c -I/home/xflm/GmSSL/include ~/apps/GmSSL/lib/libcrypto.a
# 静态连接直接运行即可
$ ./a.out
SM3: CBDDDB......
# 可执行文件较大
$ du -bs a.out
18513 a.out
5. python调用GmSSL
最近在学习python但还是菜鸡一个,摸了半天整了个能用的:
test.py
#!/bin/env python from ctypes import * class sm3_ctx_t(Structure): _fields_ = [ ('digest', c_uint * 8), ('nblocks', c_longlong), ('block', c_ubyte * 64), ('num', c_int) ] crypto = CDLL('/home/xflm/apps/GmSSL/libcrypto.so') sm3 = sm3_ctx_t() msg = c_char_p(b'1') digest = create_string_buffer(32) crypto.sm3_init(byref(sm3)) crypto.sm3_update(byref(sm3), msg, len(msg.value)) crypto.sm3_final(byref(sm3), byref(digest)) print('SM3 =', digest.raw.hex())
执行一下试试:
$ py test.py # 由于系统的python版本比较低,我在自己的目录下安装了python 3.8.6,此处我用这个版本的pyhon来执行
SM3 = cbdddb......
6. gmssl程序链接静态库
由于安装在自己的目录下,gmssl命令需要动态库,会比较麻烦,最近发现可以解决这个问题。
执行完./config --prefix=/home/xflm/apps/GmSSL
后,打开Makefile,搜索apps/gmssl
,找到其链接的位置,将libssl.so
libcrypto.so
改为libssl.a
libcrypto.a
,然后编译安装,最终编译的gmssl命令将不再需要指定动态库了。