
暂无个人介绍
能力说明:
掌握计算机基础知识,初步了解Linux系统特性、安装步骤以及基本命令和操作;具备计算机基础网络知识与数据通信基础知识。
暂时未有相关云产品技术能力~
阿里云技能认证
详细说明1 背景 国密SSL在实际上线和使用过程中,性能就是一个必须面对的问题。 国密SSL和标准SSL相比,算一个新生事物,没有完善齐备的性能测试工具。 本文针对国密SSL性能测试,描述了相关指标,并提供一些基本的方法和工具, 也做了nginx/tomcat/硬件网关的测试对比。 2 国密SSL性能指标 国密SSL性能指标主要有三个:新建速率(CPS,Connection per second)、加密吞吐(Throughput)、最大并发连接(Max Persistent Connections) 其中CPS和吞吐与性能强相关,最大并发连接和内存大小强相关。 2.1 新建速率CPS CPS衡量的是国密SSL建立的快慢(主要涉及非对称密码处理),新建指的是以下步骤的总和: 1) 客户端与服务器/网关建立TCP; 2) 客户端与服务器/网关建立国密SSL(不使用会话重用); 3) 客户端从服务器/网关下载一个小页面(不使用HTTP的Keep-Alive),页面大小为64字节或者1K字节; 4) 客户端与服务器/网关关闭国密SSL; 5) 客户端与服务器/网关关闭TCP; 2.2 加密吞吐 加密吞吐衡量的是国密SSL对数据加解密的快慢(主要涉及对称密码处理),通常测试下载一个较大的页面,比如下载1M字节页面。 2.3 最大并发连接 最大并发连接主要看国密SSL服务器/网关能够同时保持多个在线连接,通常可以建立好连接,下载一个小页面,然后做Keep-Alive保持,不断新增加连接,直到增加会出错。 3 国密SSL性能分析 国密SSL,以算法SM2_SM4_SM3为例,主要涉及SM2、SM3、SM4的密码处理。其中新建速率与SM2性能强相关,加密吞吐则与SM3/SM4性能强相关。 另外SM2算法有其自身特点。基本上签名的速度>验签的速度,同时SM2加密速度 结合到国密SSL协议,则通常出现一个现象: 1) 单向国密SSL使用SM2算法,客户端比服务器端更消耗性能,因为客户端是SM2加密; 2) 单向标准SSL使用RSA算法,服务器端比客户端更消耗性能,因为客户端是RSA加密; 4 国密SSL性能测试方法 4.1 拓扑 图1 测试拓扑 4.2 硬件测试仪 标准SSL硬件测试仪主要有思博伦的avalanche等,目前不清楚是否支持国密SSL协议,或者支持国密SSL插件。国内硬件测试仪情况不详。 4.3 LoadRunner LoadRunner是软件测试性能的方法之一。好消息是LoadRunner支持第三方插件,通过第三方插件就能够支持国密SSL协议。 4.4 gmab Apache ab也可以支持标准SSL协议性能测试,但不支持国密。但ab是有源码的,可以自行增加国密SSL协议支持。 www.gmssl.cn提供一个国密ab的实现,软件名称叫gmab。下载参见: https://www.gmssl.cn/gmssl/index.jsp?go=down 4.5 gmkb 前面分析到,对于国密SSL而言,客户端的性能消耗要大于服务器/网关端的性能消耗,因此使用LoadRunner和gmab的话,需要多台高性能客户端压力机。 www.gmssl.cn提供一个国密SSL性能测试的“黑”科技软件gmkb,能够通过一个客户端压力机就可以简单评估出服务器/网关的国密SSL的CPS性能。下载参见: https://www.gmssl.cn/gmssl/index.jsp?go=down 4.6 gmcb www.gmssl.cn提供一个国密SSL性能测试加密吞吐的软件gmcb,能够通过一个或者多个客户端压力机测试出服务器/网关的国密SSL的加密吞吐性能。下载参见: https://www.gmssl.cn/gmssl/index.jsp?go=down 5 国密SSL性能测试结果 5.1 Web服务器 通过gmab和gmcb,我们简单测试了www.gmssl.cn的nginx国密SSL性能和tomcat的国密SSL性能。测试的单向国密SSL的性能,服务器为CentoOS7,CPU为Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz,内存为16G,网卡为intel万兆电口。 Nginx国密版本1.8.0,安装下载参见https://www.gmssl.cn/gmssl/index.jsp?go=nginx 国密Nginx性能如下: 新建:3600 吞吐:693MBps 并发:50w Tomcat国密版本9.0.37,安装下载参见https://www.gmssl.cn/gmssl/index.jsp?go=tomcat 国密Tomcat性能如下: 新建:720 吞吐:240MBps(字节/秒) 并发:8192(内存实际用的很少,tomcat报错,没有继续深入) 5.2 硬件网关 作为对比,我们拿到了北京云钥网络科技有限公司(www.keyaas.com)的硬件国密网关KSG2500的性能数据,KSG2500性能给人印象深刻,毕竟是一款高端专业硬件网关。KGS2500性能: 新建:5w 吞吐:2GBps(字节/秒) 并发:300w 6 国密SSL性能测试小结 本文涉及了国密SSL性能的方方面面,并且给出了www.gmssl.cn的国密nginx和国密tomcat的实测性能数据,也对比了硬件网关KSG2500的性能数据。
背景 国密SSL协议使用双证书体系。本文描述了国密双证书体系的组成和差别,并描述了在U盾里面的使用情况。 国密SSL双证书 国密SSL协议使用双证书体系,分别称为签名证书和加密证书,服务器和用户持有两对SM2独立的密钥对。其中加密证书和签名证书主要的区别就是密钥用法(KeyUsage)不一样(当然对应的密钥等也不一样),使用相同的DN。密钥用法具体是:签名证书:Digital Signature, Non-Repudiation (c0)加密证书:Key Encipherment, Data Encipherment, Key Agreement (38) 国密SSL加密证书的颁发流程 国密CA体系里面,加密密钥对是在CA端产生的,和通常的签名证书流程不一样(签名密钥对通常是用户自己产生的,发送证书请求给CA来申请证书)。 那用户怎么安全获得加密证书和私钥呢?国密规范规定,加密私钥需要通过数字信封使用用户的签名公钥加密。CA将加密私钥密文返回给用户,用户因为有对应的签名私钥,因此只有该用户才可以解开密文,获得加密私钥。过程如下: 1)用户使用U盾产生签名密钥对,生成签名证书请求,发送签名证书请求给CA; 2)CA审核生成签名证书,产生加密密钥对,生成加密证书; 3)CA生成对称密钥,使用用户签名公钥加密,输出对称密钥密文; 4)CA使用对称密钥,加密用户加密私钥,输出加密私钥密文; 5)CA返回给用户签名证书、加密证书、对称密钥密文和加密私钥密文; 6)用户导入对称密钥密文,使用U盾内部签名私钥解密,获得对称密钥句柄; 7)用户使用对称密钥句柄解密加密私钥,获得加密私钥明文。 用户使用SKF(U盾)接口时,6)和7)以及导入加密证书时,使用一个API一步完成的,所述过程是在U盾内部的处理。 国密U盾伴侣 目前大部分国密U盾的管理工具,并不支持国密证书请求产生和国密证书应答导入。www.GMSSL.cn提供一个《国密U盾辅助工具》,支持国密生成证书请求/导入证书应答操作。目前支持龙脉科技的mToken GM3000。下载请参见https://www.gmssl.cn/gmssl/index.jsp?go=ukey1)生成证书请求2)提交签名证书请求给https://www.gmssl.cn/gmssl/index.jsp?go=ca3)www.gmssl.cn生成签名证书/加密证书/加密私钥密文4)导入证书应答 国密测试CA www.GMSSL.cn提供一个国密测试CA。通过国密CA,配合国密U盾伴侣,可以给用户生成国密双证书,然后可以通过国密浏览器,就使用证书登录国密双向认证的网站了。CA参见https://www.gmssl.cn/gmssl/index.jsp?go=ca
背景 OpenSSL支持标准的SSL协议,但并不支持国密SSL协议。本文描述了C语言使用国密版OpenSSL开发一个简单的客户端程序,连接国密Web网站,发送HTTP请求,并接收HTTP应答。 环境 Centos7 X64。 国密OpenSSL。下载参https://www.gmssl.cn/gmssl/index.jsp?go=gmsdk 将国密OpenSSL 展开为/usr/local/gmssl_10 源码 #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/gm.h> #define MAXBUF 4096 int main(int argc, char *argv[]) { struct sockaddr_in serveraddr; struct hostent *host; int sockfd, len; SSL *ssl = NULL; int bi = 0; if (argc < 4) { printf("./%s addr port uri sig.pem sig.key enc.pem enc.key\n", argv[0]); printf("optional: sig.pem sig.key enc.pem enc.key\n"); exit(1); } if (argc == 8) { bi = 1; } char *addr = argv[1]; int port = atoi(argv[2]); char *uri = argv[3]; char *sigCrt = argv[4]; char *sigKey = argv[5]; char *encCrt = argv[6]; char *encKey = argv[7]; // 国密SSL初始化 GM_load_library(); // 国密SSL生成SSL_CTX const SSL_METHOD *method = GMv1_1_client_method(); SSL_CTX *ctx = SSL_CTX_new(method); if (!ctx) { printf("create ctx is failed.\n"); exit(1); } // load gm sign keypair if(bi) { if (SSL_CTX_use_certificate_chain_file(ctx, sigCrt) <= 0) { printf("unable to get certificate from '%s'\n",sigCrt); //ERR_print_errors(bio_err); exit(1); } if (SSL_CTX_use_PrivateKey_file(ctx, sigKey, SSL_FILETYPE_PEM) <= 0) { printf("unable to get private key from '%s'\n",sigKey); //ERR_print_errors(bio_err); exit(1); } } // load gm enc keypair if(bi) { if (SSL_CTX_use_encrypt_cert_file(ctx, encCrt) <= 0) { printf("unable to get certificate(enc) from '%s'\n",encCrt); //ERR_print_errors(bio_err); exit(1); } if (SSL_CTX_use_encrypt_PrivateKey_file(ctx, encKey, SSL_FILETYPE_PEM) <= 0) { printf("unable to get private key(enc) from '%s'\n",encKey); //ERR_print_errors(bio_err); exit(1); } } if((host = gethostbyname(addr))==0) { printf("Error resolving host %s\n", addr); exit(1); } char *ip = inet_ntoa(*(struct in_addr*)host->h_addr_list[0]); sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; inet_pton(AF_INET, ip, &serveraddr.sin_addr.s_addr); serveraddr.sin_port = htons(port); int ok = connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)); if(ok != 0) { printf("connnect failed\n"); exit(0); } ssl = SSL_new(ctx); if (ssl == NULL) { printf("SSL_new error.\n"); exit(0); } SSL_set_fd(ssl, sockfd); if (SSL_connect(ssl) == -1) { printf("SSL_connect fail.\n"); ERR_print_errors_fp(stderr); exit(1); } else { printf("Connected with %s encryption\n", SSL_get_cipher(ssl)); } // send http request { char request[1024] = { 0 }; sprintf(request, "GET %s HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Mozilla/5.0\r\nHost: %s:%s\r\nConnection: close\r\n\r\n", argv[3], argv[1], argv[2]); len = SSL_write(ssl, request, strlen(request)); if (len < 0) { printf("send failed\n"); } else { printf("send OK, %d bytes:\n%s\n", strlen(request), request); } } // read http response { char buffer[MAXBUF + 1]; memset(buffer, 0, MAXBUF + 1); len = SSL_read(ssl, buffer, MAXBUF); if (len > 0) { printf("read OK, %d bytes: \n%s\n", len, buffer); } else { printf("recv failed\n"); goto finish; } } finish: SSL_shutdown(ssl); SSL_free(ssl); close(sockfd); SSL_CTX_free(ctx); return 0; } 测试运行 编译gcc -o test -ldl -lm test.c /usr/local/gmssl_10/lib/libssl.a /usr/local/gmssl_10/lib/libcrypto.a -I/usr/local/gmssl_10/include运行单向国密SSL网站./test demo.gmssl.cn 443 /双向国密SSL网站./test demo.gmssl.cn 444 /cert.jsp sig.crt sig.key enc.crt enc.key 备注 1)搭建单向/双向国密web服务器,可以参见https://www.gmssl.cn,提供nginx/apache/tomcat支持。2)申请国密双证书,参见https://www.gmssl.cn/gmssl/index.jsp?go=ca3)https://demo.gmssl.cn是一个单向国密Web网站4)https://demo.gmssl.cn:444是一个双向国密Web网站 小结 通过使用国密OpenSSL,C语言很容易编程来使用国密SSL连接国密Web网站。www.gmssl.cn提供了全部免费的测试组件,并且支持双向国密SSL,可供学习和测试。
背景 Java自身通过JCE和JSSE支持标准的SSL协议,但并不支持国密SSL协议。本文描述了Java使用国密JCE和国密JSSE开发一个简单的客户端程序,连接国密Web网站,发送HTTP请求,并接收HTTP应答。 环境 JRE是jre8。 国密JCE和国密JSSE。下载参 https://www.gmssl.cn/gmssl/index.jsp?go=gmsdk gmjce.jar和gmjsse.jar放到jre的lib/ext/目录下 源码 package cn.gmssl.test; import java.net.*; import java.io.*; import java.security.*; import java.security.cert.*; import javax.net.*; import javax.net.ssl.*; public class SocketGet { public static void main(String[] args) { SocketFactory fact = null; SSLSocket socket = null; String addr = "ebssec.boc.cn"; int port = 443; String uri = "/"; try { if(args.length > 0) { addr = args[0]; port = Integer.parseInt(args[1]); uri = args[2]; } System.out.println("\r\naddr="+addr); System.out.println("port="+port); System.out.println("uri="+uri); // 加载国密提供者 Security.insertProviderAt(new cn.gmssl.jce.provider.GMJCE(), 1); Security.insertProviderAt(new cn.gmssl.jsse.provider.GMJSSE(), 2); fact = createSocketFactory(null, null); socket = (SSLSocket)fact.createSocket(); socket.setTcpNoDelay(true); System.out.println("\r\nGM SSL connecting..."); socket.connect(new InetSocketAddress(addr, port), 5000); socket.setTcpNoDelay(true); socket.startHandshake(); System.out.println("Connected!\n"); DataInputStream in = new DataInputStream(socket.getInputStream()); OutputStream out = socket.getOutputStream(); String s = "GET " + uri + " HTTP/1.1\r\n"; s+= "Accept: */*\r\n"; s+= "User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)\r\n"; s+= "Host: " + addr + (port == 443 ? "" : ":"+port) + "\r\n"; s+= "Connection: Close\r\n"; s+= "\r\n"; out.write(s.getBytes()); out.flush(); // 读取HTTP头 while(true) { byte[] lineBuffer = ReadLine.read(in); if ( lineBuffer == null || lineBuffer.length == 0) { System.out.println(); break; } String line = new String(lineBuffer); System.out.println(line); } // 读取HTTP内容 { byte[] buf = new byte[1024]; while(true) { int len = in.read(buf); if(len == -1) { break; } System.out.println(new String(buf, 0, len)); } } in.close(); out.close(); } catch(Exception e) { e.printStackTrace(); } finally { try { socket.close(); } catch(Exception e) {} } } private static SSLSocketFactory createSocketFactory(KeyStore kepair, char[] pwd) throws Exception { X509TrustManager[] trust = { new MyTrustAllManager() }; KeyManager[] kms = null; if (kepair != null) { KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(kepair, pwd); kms = kmf.getKeyManagers(); } // 使用国密SSL String protocol = cn.gmssl.jsse.provider.GMJSSE.GMSSLv11; String provider = cn.gmssl.jsse.provider.GMJSSE.NAME; SSLContext ctx = SSLContext.getInstance(protocol, provider); java.security.SecureRandom secureRandom = new java.security.SecureRandom(); ctx.init(kms, trust, secureRandom); SSLSocketFactory factory = ctx.getSocketFactory(); return factory; } } class MyTrustAllManager implements X509TrustManager { private X509Certificate[] issuers; public MyTrustAllManager() { this.issuers = new X509Certificate[0]; } public X509Certificate[] getAcceptedIssuers() { return issuers ; } public void checkClientTrusted(X509Certificate[] chain, String authType) {} public void checkServerTrusted(X509Certificate[] chain, String authType) {} } class ReadLine { public static final byte[] CRLF = {'\r', '\n'}; public static final byte CR = '\r'; public static final byte LF = '\n'; private static final int LINE_MAX_SIZE = 16384; public static byte[] read(DataInputStream in) throws IOException, SocketException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream s = new DataOutputStream(baos); boolean previousIsCR = false; int len = 0; byte b = 0; try { b = in.readByte(); len ++; } catch(EOFException e) { return new byte[0]; } while(true) { if(b == LF) { if(previousIsCR) { s.flush(); byte[] rs = baos.toByteArray(); s.close(); return rs; } else { s.flush(); byte[] rs = baos.toByteArray(); s.close(); return rs; } } else if(b == CR) { if(previousIsCR) { s.writeByte(CR); } previousIsCR = true; } else { if(previousIsCR) { s.writeByte(CR); } previousIsCR = false; s.write(b); } if(len > LINE_MAX_SIZE) { s.close(); throw new IOException("Reach line size limit"); } try { b = in.readByte(); len ++; } catch(EOFException e) { s.flush(); byte[] rs = baos.toByteArray(); s.close(); return rs; } } } } 注释 首先要注册国密提供者 Security.insertProviderAt(new cn.gmssl.jce.provider.GMJCE(), 1); Security.insertProviderAt(new cn.gmssl.jsse.provider.GMJSSE(), 2); 其中要使用国密SSL来连接 String protocol = cn.gmssl.jsse.provider.GMJSSE.GMSSLv11; String provider = cn.gmssl.jsse.provider.GMJSSE.NAME; SSLContext ctx = SSLContext.getInstance(protocol, provider); 是不是比想象中要简单? 测试运行 >java cn.gmssl.test.SocketGet addr=ebssec.boc.cnport=443uri=/ GM SSL connecting...Connected! HTTP/1.1 200 OKDate: Mon, 24 Aug 2020 03:45:28 GMTLast-Modified: Sat, 27 Jun 2015 16:48:38 GMTAccept-Ranges: bytesContent-Length: 156Cache-Control: max-age=300Expires: Mon, 24 Aug 2020 03:50:28 GMTVary: Accept-Encoding,User-AgentConnection: closeContent-Type: text/html... 小结 通过使用国密JCE和国密JSSE,Java很容易编程来使用国密SSL连接国密Web网站。www.gmssl.cn提供了全部免费的测试组件,并且支持双向国密SSL,可供学习和测试。
背景 Nginx自身支持标准的SSL协议,但并不支持国密SSL协议。本文描述了Nginx配置的国密SSL协议(单向)的完整过程,仅供学习和参考之用。特点:Nginx 无需改动源码、支持任意版本。 环境 服务器OS是CentOS7.7的64位版本,IP位192.168.0.98,客户端OS是WindowsXP。 Nginx是Nginx-1.18.0。 浏览器是360安全浏览器(支持国密)。 安装方法一:源码编译 GMSSL.cn提供一个OpenSSL的国密版库,可与nginx编译,生成的nginx即支持国密SSL协议。1)准备gmssl_openssl下载页面https://www.gmssl.cn/gmssl/index.jsp?go=nginxdown下载其中的gmssl_openssl_1.1_b1.tar.gz下载页面https://www.gmssl.cn/gmssl/index.jsp?go=nginxdown拷贝到/root/目录解压 tar xzfm gmssl_openssl_1.1_bxx.tar.gz -C /usr/local 则/usr/local/gmssl为国密版openssl目录2)准备nginx下载页面http://nginx.org/download/nginx-1.18.0.tar.gz拷贝到/root/目录解压 tar xzfm nginx-1.18.0.tar.gz 则/root/nginx-1.18.0为nginx目录cd /root/nginx-1.18.0vi auto/lib/openssl/conf,将全部$OPENSSL/.openssl/修改为$OPENSSL/并保存3)编译./configure \--without-http_gzip_module \--with-http_ssl_module \--with-http_stub_status_module \--with-http_v2_module \--with-file-aio \--with-openssl="/usr/local/gmssl" \--with-cc-opt="-I/usr/local/gmssl/include" \--with-ld-opt="-lm"make install则/usr/local/nginx为生成的国密版nginx目录注:可能需要安装需要的pcre-devel包。 安装方法二:直接安装 GMSSL.cn已经提供了一个按方法一编译好的国密版nginx,可以直接下载安装使用。 下载页面https://www.gmssl.cn/gmssl/index.jsp?go=nginxdown 下载其中的gmssl_nginx_1.8.0_b7.tar.gz 拷贝到/root/目录解压 tar zxfm gmssl_nginx_1.8.0_bxxx.tar.gz -C /usr/local **则/usr/local/nginx为国密版nginx目录 国密双证书 1)生成国密双证书访问https://www.gmssl.cn/gmssl/index.jsp?go=ca可生成免费的测试国密双证书。提交后保存sm2.demo1.gmssl.cn.zip传到服务器/root/下解压unzip sm2.demo1.gmssl.cn.zip -d /root/sm2.demo1/ Nginx部署国密SSL 1)配置Nginxvi /usr/local/nginx/conf/nginx.confhttp下加入server{ listen 0.0.0.0:443 ssl; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphersECDHE-RSA-AES128-GCM-SHA256:AES128-SHA:DES-CBC3-SHA:ECC-SM4-SM3:ECDHE-SM4-SM3; ssl_verify_client off; ssl_certificate/root/sm2.demo1/sm2.demo1.gmssl.cn.sig.crt.pem; ssl_certificate_key/root/sm2.demo1/sm2.demo1.gmssl.cn.sig.key.pem; ssl_certificate/root/sm2.demo1/sm2.demo1.gmssl.cn.enc.crt.pem; ssl_certificate_key/root/sm2.demo1/sm2.demo1.gmssl.cn.enc.key.pem; location / { root html; index index.html index.htm; }}2)测试/usr/local/nginx/sbin/nginx-tOpenSSL(GM version) by www.gmssl.cn.Test Only!!!OpenSSL(GM version) bywww.gmssl.cn. Test Only!!!OpenSSL(GM version) bywww.gmssl.cn. Test Only!!!OpenSSL(GM version) bywww.gmssl.cn. Test Only!!!nginx: the configuration file/usr/local/nginx/conf/nginx.conf syntax is oknginx: configuration file/usr/local/nginx/conf/nginx.conf test is successful注:Test Only等信息是国密版OpenSSL输出的提示信息,不影响测试和使用。3)运行/usr/local/nginx/sbin/nginx 访问验证 1)下载360安全浏览器https://se.360.cn2)开启国密SSL支持3)启用极速模式访问https://192.168.0.98,出现错误页面,开启极速模式4)访问国密SSL成功 小结 通过使用国密SSL组件,使得Nginx自身不做任何编译修改,即可比较简单的支持国密SSL协议,满足等保等政策合规,确实是一个简单可操作的方法。gmssl.cn提供了全部免费的测试组件,并且支持双向国密SSL,支持国密SSL/标准 SSL自适应,也支持Tomcat和Apache,值得推荐和试用。
背景 Tomcat自身支持标准的SSL协议,但并不支持国密SSL协议。本文描述了Tomcat配置的国密SSL协议(单向)的完整过程,仅供学习和参考之用。特点:Tomcat 无需改动源码、无需重新编译、支持任意版本。 环境 服务器OS是CentOS7.7的64位版本,IP位192.168.0.97,客户端OS是WindowsXP。JRE是jre-8u212-linux-x64.rpm。Tomcat是apache-tomcat-9.0.37.tar.gz。浏览器是360安全浏览器(支持国密)。 国密双证书 1) 生成国密双证书访问https://www.gmssl.cn可生成免费的测试国密双证书。提交后保存sm2.demo1.gmssl.cn.zip传到服务器/root/下解压unzip sm2.demo1.gmssl.cn.zip -d /root/sm2.demo1/其中/root/sm2.demo1/sm2.demo1.gmssl.cn.both.pfx是PFX格式的国密双证书/私钥文件,默认口令是12345678。 Tomcat部署国密SSL 1) 安装JRErpm -i jre-8u212-linux-x64.rpm2) 部署Tomcat/root/下解压Tomcattar zxfm apache-tomcat-9.0.37.tar.gz3) 部署Java版本国密SSL组件下载国密SSL组件其中gmjce.jar和gmjsse.jar放到/usr/java/jre1.8.0_212-amd64/lib/ext/下gmssl4t.jar/root/apache-tomcat-9.0.37/lib/4)配置Tomcatvi /root/apache-tomcat-9.0.37/conf/server.xmlService下加入 <Connector port="443"protocol="HTTP/1.1"SSLEnabled="true" sslImplementationName="cn.gmssl.tomcat.GMSSLImplementation"sslProtocol="GMSSLv1.1"keystoreFile="/root/sm2.demo1/sm2.demo1.gmssl.cn.both.pfx"keystoreType="PKCS12"keystorePass="12345678"></Connector> 5)启动Tomcat/root/apache-tomcat-9.0.37/bin/startup.sh 访问验证 1)下载360安全浏览器https://se.360.cn2)开启国密SSL支持3)启用极速模式访问https://192.168.0.97,出现错误页面,开启极速模式4)访问国密SSL成功 小结 通过使用国密SSL组件,使得Tomcat自身不做任何编译修改,即可比较简单的支持国密SSL协议,满足等保等政策合规,确实是一个简单可操作的方法。www.gmssl.cn提供了全部免费的测试组件,并且支持双向国密SSL,支持国密SSL/标准 SSL自适应,也支持Nginx和Apache,值得推荐和试用。
背景 Apache httpd自身支持标准的SSL协议,但并不支持国密SSL协议。本文描述了Apache httpd配置的国密SSL协议(单向)的完整过程,仅供学习和参考之用。特点:Apache httpd 无需改动源码、支持任意版本。 环境 服务器OS是CentOS7.7的64位版本,IP位192.168.0.96,客户端OS是WindowsXP。 CentOS7.7需安装development tools 开发环境, 如未安装,后续编译过程需安装必要开发包(已注明)。 Apache httpd是httpd-2.4.46.tar.gz 。 浏览器是360安全浏览器(支持国密)。 安装方法一:源码编译 GMSSL.cn提供一个OpenSSL的国密版库,可与Apache httpd编译,生成的Apache httpd即支持国密SSL协议。1) 准备gmssl_openssl 下载页面https://www.gmssl.cn/gmssl/index.jsp?go=nginxdown 下载其中的gmssl_openssl_1.1_bx.tar.gz 拷贝到/root/目录解压tar xzfm gmssl_openssl_1.1_bxx.tar.gz -C /usr/local则/usr/local/gmssl为国密版openssl目录2) 准备Apache httpd安装必要开发包:yum install pcre-develyum install expat-devel编译apr:下载https://mirror.bit.edu.cn/apache//apr/apr-1.7.0.tar.gztar zxfm apr-1.7.0.tar.gzcd apr-1.7.0./configure --prefix=/usr/local/apr/aprmake install编译apr-util:下载https://mirrors.bfsu.edu.cn/apache//apr/apr-util-1.6.1.tar.gztar zxfm apr-util-1.6.1.tar.gzcd apr-util-1.6.1./configure --prefix=/usr/local/apr/util --with-apr=/usr/local/apr/aprmake install下载展开Apache httpd:下载https://mirrors.tuna.tsinghua.edu.cn/apache//httpd/httpd-2.4.46.tar.gztar zxfm httpd-2.4.46.tar.gzcd httpd-2.4.463) 编译安装必要开发包:yum install -y bison bison-develyum install -y flex flex-devel配置:./configure --prefix=/usr/local/httpd --enable-so --enable-ssl --enable-cgi --enable-rewrite --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork --with-zlib --with- apr=/usr/local/apr/apr --with-apr-util=/usr/local/apr/util --with-ssl=/usr/local/gmssl LDFLAGS=-lm修改ssl为静态链接:/vi build/config_vars.mk找到ab_LIBS = -L/usr/local/gmssl/lib -lssl -lcrypto -lrt -lcrypt -lpthread -ldl去掉-L/usr/local/gmssl/lib -lssl -lcrypto 增加/usr/local/gmssl/lib/libssl.a /usr/local/gmssl/lib/libcrypto.amake install则/usr/local/httpd为生成的国密版Apache httpd目录 安装方法二:直接安装 GMSSL.cn已经提供了一个按方法一编译好的国密版httpd,可以直接下载安装使用。 下载页面https://www.gmssl.cn/gmssl/index.jsp?go=apachedown 下载其中的gmssl_httpd_2.4.46_b6.tar.gz 拷贝到/root/目录解压 tar zxfm gmssl_httpd_2.4.46_b6.tar.gz -C /usr/local 则/usr/local/http为国密版Apache httpd目录 国密双证书 1) 生成国密双证书访问https://www.gmssl.cn/gmssl/index.jsp?go=ca可生成免费的测试国密双证书。提交后保存sm2.demo1.gmssl.cn.zip传到服务器/root/下解压unzip sm2.demo1.gmssl.cn.zip -d /root/sm2.demo1/ Apache httpd部署国密SSL 1) 开启SSLvi /usr/local/httpd/conf/httpd.conf取掉注释LoadModule ssl_module modules/mod_ssl.so取消注释Include conf/extra/httpd-ssl.conf2)配置vi /usr/local/httpd/conf/extra/httpd-ssl.conf注释掉所有带SSLSessionCache的配置行配置算法 SSLCipherSuite HIGH:ECC-SM4-SM3:ECDHE-SM4-SM3 注释掉默认证书和key #SSLCertificateFile "/usr/local/httpd/conf/server.crt" #SSLCertificateKeyFile "/usr/local/httpd/conf/server.key" 配置国密双证书/私钥 SSLCertificateFile"/root/sm2.demo1/sm2.demo1.gmssl.cn.sig.crt.pem" SSLCertificateKeyFile"/root/sm2.demo1/sm2.demo1.gmssl.cn.sig.key.pem" SSLCertificateFile "/root/sm2.demo1/sm2.demo1.gmssl.cn.enc.crt.pem" SSLCertificateKeyFile "/root/sm2.demo1/sm2.demo1.gmssl.cn.enc.key.pem" 3)测试启动测试/usr/local/httpd/bin/httpd -tOpenSSL(GM version) by www.gmssl.cn. Test Only!!!OpenSSL(GM version) by www.gmssl.cn. Test Only!!!AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::7747:d82a:32df:f84c%ens33. Set the 'ServerName' directive globally to suppress this messageSyntax OK启动/usr/local/httpd/bin/httpd -k startOpenSSL(GM version) by www.gmssl.cn. Test Only!!!OpenSSL(GM version) by www.gmssl.cn. Test Only!!!AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::7747:d82a:32df:f84c%ens33. Set the 'ServerName' directive globally to suppress this messageOpenSSL(GM version) by www.gmssl.cn. Test Only!!!注:Test Only等信息是国密版OpenSSL输出的提示信息,不影响测试和使用。 访问验证 1)下载360安全浏览器https://se.360.cn2)开启国密SSL支持3)启用极速模式访问https://192.168.0.96出现错误页面,开启极速模式4)访问国密SSL成功 小结 通过使用国密SSL组件,使得Apache httpd自身不做任何编译修改,即可比较简单的支持国密SSL协议,满足等保等政策合规,确实是一个简单可操作的方法。gmssl.cn提供了全部免费的测试组件,并且支持双向国密SSL,支持国密SSL/标准 SSL自适应,也支持Tomcat和Nginx,值得推荐和试用。
2020年09月
2020年08月