死磕GMSSL通信-C/C++系列(一)
最近再做国密通信的项目开发,以为国密也就简单的集成一个库就可以完事了,没想到能有这么多坑。遂写下文章,避免重复踩坑。以下国密通信的坑有以下场景
1、使用GMSSL guanzhi/GmSSL进行通信
2、使用加密套件SM2-WITH-SMS4-SM3
使用心得
GmSSL这个库的问题很多,发现许多库和它都不能正常通信,都需要修改代码,不是修改客户端就是修改服务端,而且这个开源项目基本处于不维护的状态,如果准备集成的GM通信的,优先选择铜锁/Tongsuo 这个项目,毕竟背后是商业公司在维护。
1、经过最近几天的测试,发现
window编译
网上有好多编译教程,我这里也不细说了,大概步骤如下
安装Perl软件:从Perl官网(https://www.activestate.com/products/perl/downloads/)下载安装包直接安装就行了。安装完好后命令行执行【perl -v】就可以查看版本信息
以64位为列,打开“ VS2015 x64 本机工具命令提示符”
执行:perl Configure VC-WIN64A no-asm no-shared
- VC-WIN32 表示编译选项生成32位的库
- VC-WIN64A 表示编译选项生成64位的库
- VC-WIN64I 表示编译选项生成IA64的库,使用安腾cpu的需要使用此选项,安腾x64架构是inter自家的,比较少见
- no-asm 表示不使用汇编,如果本地安装了nasm工具,可以不使用此选项
- –prefix=D:xxx\xx 表示输出目录
执行nmake
最后程序根目录生成俩个静态库 libcrypto.lib、libssl.lib
生成证书
这里就不提供证书生成的过程了,网上生成的教程很多,GMSSL需要五个证书
-
CA.cert.pem
-
SE.cert.pem
-
SE.key.pem
-
SS.cert.pem
-
SS.key.pem
[注意]
理论上客户端和服务端的证书应该是俩套,也可以直接客户端和服务器用一样的证书,我这里直接用了一套,大家可以自行测试俩套的
GMSSL双向通信
server端代码
/** Copyright 1998-2016 The OpenSSL Project Authors. All Rights Reserved.** Licensed under the OpenSSL license (the "License"). You may not use* this file except in compliance with the License. You can obtain a copy* in the file LICENSE in the source distribution or at* https://www.openssl.org/source/license.html*//*-* A minimal program to serve an SSL connection.* It uses blocking.* saccept host:port* host is the interface IP to use. If any interface, use *:port* The default it *:4433** cc -I../../include saccept.c -L../.. -lssl -lcrypto -ldl*/#include <stdio.h>
#include <signal.h>
#include <openssl/err.h>
#include <openssl/ssl.h>#define CA_CERT_FILE "CA.cert.pem"
#define SIGN_CERT_FILE "SS.cert.pem"
#define SIGN_KEY_FILE "SS.key.pem"
#define ENCODE_CERT_FILE "SE.cert.pem"
#define ENCODE_KEY_FILE "SE.key.pem"static int done = 0;void interrupt(int sig)
{done = 1;
}int main(int argc, char* argv[])
{char* port = "0.0.0.0:9999";BIO* in = NULL;BIO* ssl_bio, * tmp;SSL_CTX* ctx;char buf[512];int ret = 1, i;ctx = SSL_CTX_new(GMTLS_server_method());SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
#if 1if (!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL)){goto err;}if (!SSL_CTX_use_certificate_file(ctx, SIGN_CERT_FILE, SSL_FILETYPE_PEM))goto err;if (!