服务器使用国密(SM2/SM3/SM4)证书,通过浏览器访问

1. Apache + Gmssl

Apache 本身不支持国密,需要修改代码支持GMTLS

  1. 下载解压:

    wget http://archive.apache.org/dist/httpd/httpd-2.4.39.tar.gz
    tar -zxf httpd-2.4.39.tar.gz
    
  2. 修改文件:Apache dir\modules\ssl\ssl_engine_init.c
    SSL_CTX_set_min_proto_version(ctx, prot);
    这一行前增加prot = GMTLS_VERSION;

安装

  1. 安装依赖

    yum install -y wget gcc gcc-c++ pcre-devel perl
    
    wget http://mirror.bit.edu.cn/apache//apr/apr-1.7.0.tar.gz
    tar -zvxf apr-1.7.0.tar.gz
    cd apr-1.7.0
    ./configure --prefix=/usr/local/apr
    make -j32 && make install
    
    wget http://archive.apache.org/dist/apr/apr-util-1.5.4.tar.gz
    tar -zvxf apr-util-1.5.4.tar.gz
    cd apr-util-1.5.4
    ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
    make -j32 && make install
    
  2. 安装gmssl

    wget https://codeload.github.com/guanzhi/GmSSL/zip/master
    unzip GmSSL-master.zip
    ./config --prefix=/usr/local/gmssl
    make -j32 && make install
    
  3. 和gmssl一起编译安装apache

    ./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 --with-apr-util=/usr/local/apr-util --with-ssl=/usr/local/gmssl
    make -j32 && make install
    
  4. 添加动态链接

    vi /etc/ld.so.conf /usr/local/gmssl/lib
    ldconfig
    

使用国密算法生成证书

  1. 配置openssl.cnf 文件
  2. 使用以下命令生成证书
    	# 生成CA证书
    	/usr/local/gmssl/bin/gmssl ecparam -genkey -name SM2 -noout -out ca.key
    	/usr/local/gmssl/bin/gmssl req -new -key ca.key -out ca.req -subj "/C=CN/O=AsiaInfo/OU=CoreTech/CN=Localhost.10.22.2.112"
    	/usr/local/gmssl/bin/gmssl x509 -req -days 3650 -sm3 -in ca.req -extfile ./openssl.cnf -extensions v3_ca -signkey ca.key -out ca.crt
    
    	# Server签名证书
    	/usr/local/gmssl/bin/openssl ecparam -name SM2 -genkey -noout -out server.key
    	/usr/local/gmssl/bin/openssl req -new -SM3 -key server.key -out server.csr -subj /C=CN/O=AsiaInfo/OU=CoreTech/CN="10.22.2.112"
    	/usr/local/gmssl/bin/openssl x509 -req -SM3 -days 3650 -in server.csr -extfile ./openssl.cnf -extensions v3_req -CA ca.crt -CAkey ca.key -set_serial 1000000001 -out server.crt
    
    	# Server加密证书
    	/usr/local/gmssl/bin/openssl ecparam -name SM2 -genkey -noout -out server_en.key
    	/usr/local/gmssl/bin/openssl req -new -SM3 -key server_en.key -out server1.csr -subj /C=CN/O=AsiaInfo/OU=CoreTech/CN="10.22.2.112"
    	/usr/local/gmssl/bin/openssl x509 -req -SM3 -days 3650 -in server1.csr -extfile ./openssl.cnf -extensions v3enc_req -CA ca.crt -CAkey ca.key -set_serial 1000002001 -out server_en.crt
    

修改http.conf

  1. 增加:
    LoadModule ssl_module modules/mod_ssl.so
    Include conf/ssl.conf
    

测试通信

  1. 命令

    # 服务器端运行
    /usr/local/gmssl/bin/openssl s_server -accept 4433 -CAfile CA.pem -cert SS.cert.pem -key SS.key.pem -cert SE.cert.pem -key SE.key.pem
    # 客户端访问
    /usr/local/gmssl/bin/openssl s_client -connect 127.0.0.1:4433 -msg -debug
    

    成功

未解决问题

  1. 通过浏览器访问会报错:
    浏览器报错:

    此网站无法提供安全连接
    10.22.2.112 使用了不受支持的协议。 ERR_SSL_VERSION_OR_CIPHER_MISMATCH
    协议不受支持
    客户端和服务器不支持一般 SSL 协议版本或加密套件

    gmssl server端报错:

    1. error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:ssl/statem/statem_srvr.c:1502:
    
    2. 140616840058688:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl/record/rec_layer_s3.c:1385:SSL alert number 40
    	---
    	no peer certificate available
    	---
    	No client certificate CA names sent
    

2. Apache + Wotrus ssl

大部分流程与 Apache + Gmssl一致,仅需将编译时所需的gmssl替换为wotrus ssl,
wotrus ssl 下载地址:
https://www.wotrus.com/download/wotrus_ssl.tar.gz
通过浏览器可以正常访问,证书显示为国密证书。

问题

若证书使用自己生成的国密证书,会证书验证不通过,提示:

please use wotrus GM signing certificate.

即只能用沃通的证书。

3. Nginx + tls

  1. 下载atls
    wget https://codeload.github.com/mrpre/atls/zip/master

  2. 安装openssl 1.1.1b
    wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1b.tar.gz

  3. 安装 openssl-devel
    yum install -y openssl-devel

  4. 编译安装Nginx1.13.12
    wget http://nginx.org/download/nginx-1.13.12.tar.gz
    tar -zxf nginx-1.13.12.tar.gz
    Nginx中./src/core/ngx_connection.h文件的struct ngx_connection_s中增加: void *a_tls;

    ./configure --add-module=/$YOURPATH/a_tls/ --with-stream --with-http_ssl_module --with-stream_ssl_module --with-openssl=/$YOURPATH/openssl/
    make -j32 && make install
    
  5. 生成签名国密证书和加密国密证书

  6. 配置

    stream {
        ....
        upstream http_up {
    		server                     127.0.0.1:80;
    	}
       server {
            listen 443;
            proxy_pass         			http_up;
            a_tls_certificate 			gm_en.cert;
            a_tls_certificate_key 		gm_en.key;
            a_tls_sign_certificate 		gm_sign.cert;
            a_tls_sign_certificate_key 	gm_sign.key;
            ssl_prefer_server_ciphers  	on;   
    		ssl_protocols       		TLSv1 TLSv1.1 TLSv1.2;
    	   	ssl_ciphers         		SM2-WITH-SMS4-SM3;
       	}
    }
    
  7. 浏览器成功显示服务端使用了国密证书

错误解决

  1. ./libcrypto.so: undefined reference to `EC_KEY_new_from_ECCPUBLICKEYBLOB’
    安装依赖yum install libtool perl-core zlib-devel -y
  2. /usr/bin/ld: /usr/local/tassl/lib/libcrypto.a(p12_add.o): relocation R_X86_64_32 against `.rodata.str1.1’ can not be used when making a shared object; recompile with -fPIC
    编译时添加shared参数
  3. openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
    export LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64
    vi /etc/ld.so.conf 添加 /usr/local/lib64 /usr/local/openssl/lib 运行ldconfig
  4. certificate not match
    可以尝试签名证书和加密证书使用同一个私钥

相关链接:

  1. Apache mod_ssl.so模块配置参数说明:
    https://httpd.apache.org/docs/current/mod/mod_ssl.html
  2. Gmssl:
    https://github.com/guanzhi/GmSSL
  3. Tassl:
    https://github.com/jntass/TASSL
  4. Tassl/Gmssl简介:
    https://www.dazhuanlan.com/2019/10/01/5d92af0087156/
  5. 证书管理脚本:
    https://blog.stdio.io/1019
  6. 国密规范
    http://www.gmbz.org.cn/main/bzlb.html
  7. atls
    https://github.com/mrpre/atls

你可能感兴趣的:(Linux,Apache,国密)