国密安装-配置-使用
- 从刚装完虚拟机开始
1. 安装所需依赖 :
vi /etc/apt/sources.list
#简单可用(某些依赖包需要从官网上拉取)
deb http://mirrors.163.com/debian/ stretch main
deb-src http://mirrors.163.com/debian/ stretch main
deb http://security.debian.org/debian-security stretch/updates main contrib
deb-src http://security.debian.org/debian-security stretch/updates main contrib
#更新并安装依赖
apt-get update
apt-get upgrade
apt-get install gcc g++ make cmake unzip net-tools wget vim luajit
2. 下载安装包
wget https://www.openssl.org/source/openssl-1.1.1h.tar.gz
wget https://github.com/guanzhi/GmSSL/archive/refs/heads/GmSSL-v2.zip
wget http://zlib.net/zlib-1.2.13.tar.gz
wget https://netix.dl.sourceforge.net/project/pcre/pcre/8.40/pcre-8.40.tar.gz
wget https://openresty.org/download/openresty-1.19.3.1.tar.gz
3. 升级OpenSSL 旧版本
自带的1.1.0d版支持的算法不全,1.1.1较全面
tar zxvf openssl-1.1.1h.tar.gz
cd openssl-1.1.1h
./config
make && make install
#备份原openssl
mv /usr/bin/openssl /usr/bin/openssl.bak
mv /usr/include/openssl /usr/include/openssl.bak
#添加软连接
ln -s /usr/local/bin/openssl /usr/bin/openssl
ln -s /usr/local/include/openssl/ /usr/include/openssl
#可以用which openssl命令查看路径,如果有神通数据库则路径如下:/opt/ShenTong/bin/openssl
ln -s /usr/bin/openssl /opt/ShenTong/bin/openssl
#将新的库文件地址写入记录so库的配置文件
echo "/usr/local/lib64" >> /etc/ld.so.conf
#设置生效
ldconfig -v
4. 解压-编译安装
tar zxvf zlib-1.2.13.tar.gz
cd zlib-1.2.13
./configure && make && make install
-----------------------------------------------------------------
tar zxvf pcre-8.40.tar.gz
cd pcre-8.40
./configure \
--prefix=/usr/local/pcre
make && make install
--------------------------------------------------------------------
unzip GmSSL-v2.zip
cd GmSSL-GmSSL-v2
./config --prefix=/usr/local/gmssl no-shared
make && make install
#添加环境变量
$echo 'export PATH="$PATH:/usr/local/gmssl/bin"' >> ~/.bash_profile
$source ~/.bash_profile
---------------------------------------------------------------------------
tar zxvf openresty-1.19.3.1.tar.gz
cd openresty-1.19.3.1
./configure \
--prefix=/usr/local/openresty \
--with-http_ssl_module \
--with-http_v2_module \
--with-stream_ssl_preread_module \
--with-cc-opt="-I/usr/local/gmssl/include -I/usr/local/pcre/include" \
--with-ld-opt="-L/usr/local/gmssl/lib -L/usr/local/pcre/lib"
--------------------------------------------------------------------------
make
make install
---------------------------------------------------------------------------
export PATH=$PATH:/usr/local/openresty/luajit/bin:/usr/local/openresty/nginx/sbin:/usr/local/openresty/bin
5. 生成证书测试
mkdir gmtest
cd gmtest
mkdir certs crl newcerts private
touch index.txt
echo "01" > serial
将openssl.cnf 导入gmtest路径下 openssl.cnf文件
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = . # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several certs with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/ca.crt # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/ca.key # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert # The extensions to add to the cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# Extension copying option: use with caution.
# copy_extensions = copy
# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crlnumber must also be commented out to leave a V1 CRL.
# crl_extensions = crl_ext
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sm3 # use public key default MD
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_anything
distinguished_name = req_distinguished_name
# For the CA policy
#[ policy_match ]
#countryName = match
#stateOrProvinceName = match
#organizationName = match
#organizationalUnitName = optional
#commonName = supplied
#emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 4096
default_md = sm3
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
#attributes = req_attributes
x509_extensions = v3_ca # The extensions to add to the self signed cert
string_mask = nombstr
# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret
# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
# utf8only: only UTF8Strings (PKIX recommendation after 2004).
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
#string_mask = utf8only
# req_extensions = v3_req # The extensions to add to a certificate request
###################################################################################
[ ssl_server ]
basicConstraints = CA:FALSE
nsCertType = server
keyUsage = digitalSignature, keyEncipherment
extendedkeyUsage = serverAuth, nsSGC, msSGC
nsComment = "OpenSSL Certificate for SSL wed Server"
[ ssl_client ]
basicConstraints = CA:FALSE
nsCertType = client
keyUsage = digitalSignature, keyEncipherment
extendedkeyUsage = clientAuth
nsComment = "OpenSSL Certificate for SSL Client"
[ server_single_cert ]
basicConstraints=CA:FALSE
nsCertType = server
keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement
[ server_sign_cert ]
basicConstraints=CA:FALSE
nsCertType = server
keyUsage = nonRepudiation,digitalSignature
[ server_enc_cert ]
basicConstraints=CA:FALSE
nsCertType = server
keyUsage = keyEncipherment,dataEncipherment,keyAgreement
[ client_single_cert ]
basicConstraints = CA:FALSE
nsCertType = client
keyUsage = nonRepudiation,digitalSignature,keyEncipherment,dataEncipherment,keyAgreement
[ client_sign_cert ]
basicConstraints = CA:FALSE
nsCertType = client
keyUsage = nonRepudiation,digitalSignature
[ client_enc_cert ]
basicConstraints = CA:FALSE
nsCertType = client
keyUsage = keyEncipherment,dataEncipherment,keyAgreement
###################################################################################
#[ req_distinguished_name ]
#countryName = Country Name (2 letter code)
#countryName_default = CN
#countryName_min = 2
#countryName_max = 2
#stateOrProvinceName = State or Province Name (full name)
#stateOrProvinceName_default = Some-State
#localityName = Locality Name (eg, city)
#0.organizationName = Organization Name (eg, company)
#0.organizationName_default = Internet Widgits Pty Ltd
# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
#organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
#commonName = Common Name (e.g. server FQDN or YOUR name)
#commonName_max = 64
#emailAddress = Email Address
#emailAddress_max = 64
# SET-ex3 = SET extension number 3
#[ req_attributes ]
#challengePassword = A challenge password
#challengePassword_min = 4
#challengePassword_max = 20
#unstructuredName = An optional company name
#[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
#basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# keyUsage = digitalSignature
#keyUsage = keyEncipherment
# This will be displayed in Netscape's comment listbox.
#nsComment = "GmSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
#subjectKeyIdentifier=hash
#authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This is required for TSA certificates.
# extendedKeyUsage = critical,timeStamping
#[ v3_req ]
# Extensions to add to a certificate request
#basicConstraints = CA:FALSE
#keyUsage = nonRepudiation, digitalSignature, keyEncipherment
[ v3_ca ]
# Extensions for a typical CA
# PKIX recommendation.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign
# Some might want this also
# nsCertType = sslCA, emailCA
# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy
# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF
#[ crl_ext ]
# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
# issuerAltName=issuer:copy
#authorityKeyIdentifier=keyid:always
#[ proxy_cert_ext ]
# These extensions should be added when creating a proxy certificate
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
#basicConstraints=CA:FALSE
# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.
# This is OK for an SSL server.
# nsCertType = server
# For an object signing certificate this would be used.
# nsCertType = objsign
# For normal client use this is typical
# nsCertType = client, email
# and for everything including object signing:
# nsCertType = client, email, objsign
# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# This will be displayed in Netscape's comment listbox.
#nsComment = "GmSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
#subjectKeyIdentifier=hash
#authorityKeyIdentifier=keyid,issuer
# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
# subjectAltName=email:move
# Copy subject details
# issuerAltName=issuer:copy
#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName
# This really needs to be in place for it to be a proxy certificate.
#proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
####################################################################
#[ tsa ]
#default_tsa = tsa_config1 # the default TSA section
#[ tsa_config1 ]
# These are used by the TSA reply generation only.
#dir = . # TSA root directory
#serial = $dir/tsaserial # The current serial number (mandatory)
#crypto_device = builtin # OpenSSL engine to use for signing
#signer_cert = $dir/tsacert.pem # The TSA signing certificate
# (optional)
#certs = $dir/cacert.pem # Certificate chain to include in reply
# (optional)
#signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
#signer_digest = sm3 # Signing digest to use. (Optional)
#default_policy = tsa_policy1 # Policy if request did not specify it
# (optional)
#other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
#digests = sm3, sha256, sha384, sha512 # Acceptable message digests (mandatory)
#accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
#clock_precision_digits = 0 # number of digits after dot. (optional)
#ordering = yes # Is ordering defined for timestamps?
# (optional, default: no)
#tsa_name = yes # Must the TSA name be included in the reply?
# (optional, default: no)
#ess_cert_id_chain = no # Must the ESS cert id chain be included?
# (optional, default: no)
准备好如上环境后,进行证书生成
创建证书生成的目录:mkdir /root/gmtest cd /root/gmtest
(按照配置文件建好对应的目录结构后,即可进行证书的颁发,具体的颁发过程主要包含以下几步:)
#1.生成CA根证书所需私钥,指定生成私钥算法为sm2以及长度256位
$gmssl ecparam -genkey -name sm2p256v1 -out ca.key
$cp ca.key private/
#2.生成签发CA证书的证书请求,指定证书主题等信息
$gmssl req -new -sm3 -key ca.key -subj /C=CN/ST=Shan\ Xi/L=SH/O=CA/OU=CA/CN=ROOT\ CA/emailAddress=rootca@gmail.com -out ca.csr
#3.自签发CA根证书
$gmssl ca -selfsign -in ca.csr -out ca.crt -config openssl.cnf -extensions v3_ca
-----------------------------------------------------------------------------------
(通过以上三步,我们就建立好了一个可以签发证书的CA。接下来即可使用该CA为通信测试的双方:服务器以及客户端,签发证书。)
国密SSL协议是双证书机制,因此需要签发签名证书与加密证书,具体的签发流程如下:
#1、创建服务器签名和加密密钥 (生成的私钥文件与ca私钥文件类似)
$gmssl ecparam -genkey -name sm2p256v1 -out server-sign.key
$gmssl ecparam -genkey -name sm2p256v1 -out server-enc.key
#2、创建服务器证书请求
$gmssl req -new -sm3 -key server-sign.key -subj /C=CN/ST=Shang\ Hai/L=SH/O=Server/OU=Server\ Sign/CN=172.16.150.8/emailAddress=server@gmail.com -out server-sign.csr
$gmssl req -new -sm3 -key server-enc.key -subj /C=CN/ST=Shang\ Hai/L=SH/O=Server/OU=Server\ Encrypt/CN=172.16.150.8/emailAddress=server@gmail.com -out server-enc.csr
#3、签发服务器双证书 (签名证书:密钥用途为数字签名 加密证书:密钥用途为加解密)
$gmssl ca -in server-sign.csr -keyfile ./private/ca.key -cert ca.crt -out server-sign.pem -extensions server_sign_cert -config openssl.cnf
$gmssl ca -in server-enc.csr -keyfile ./private/ca.key -cert ca.crt -out server-enc.pem -extensions server_enc_cert -config openssl.cnf
(通过以上三个步骤,即准备完成服务器所需密钥及证书,接下来签发客户端双证书的流程与上类似)
(通过上面的过程,目前已具备测试国密SSL协议的根证书,服务器客户端证书及私钥,接下来可以借助gmssl的s_server与s_client组件进行通信测试)
(通信测试需要开启两个终端,一个作为服务器,另一个作为客户端
#首先开启服务器端,进入监听状态,(其中 -gmtls参数指定通信协议类型,-key参数指定通信所需签名私钥,-cert参数指定签名证书,-dkey参数指定通信所需加密私钥,-dcert参数指定加密证书 -CAfile指定根证书 -verify参数证明开启双向认证,双向认证即为在通信过程中不仅客户端需要验证服务器身份,服务器也要验证客户端身份,保证双方可信)
$gmssl s_server -gmtls -key server-sign.key -cert server-sign.pem -dkey server-enc.key -dcert server-enc.pem -CAfile ca.crt -verify 1
下一步打开客户端进行连接。
(连接后服务器日志如下所示证明已有客户端成功连接,并通过SM2-WITH-SMS4-SM3算法套件协商成功)
(客户端日志如下所示:证明握手成功,验证通过,同时协商出主密钥。)
(接下来,服务器与客户端即可加密通信传输报文,通过下图表示通信测试成功)
( 以上即为国密CA的创建,国密证书签发以及国密SSL协议通信测试的完整流程,通信过程中使用的SM2-WITH-SMS4-SM3算法套件,GMTLS协议版本为1.1。)
6. openresty-nginx配置 nginx.conf文件
worker_processes 2;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:AES128-SHA:DES-CBC3-SHA:ECC-SM4-CBC-SM3:ECDHE-SM4-GCM-SM3:SM2-WITH-SMS4-SM3;
ssl_verify_client off;
# ssl_certificate /root/gmtest/ca.crt;
# ssl_certificate_key /root/gmtest/ca.key;
ssl_certificate /root/gmtest/server-enc.crt;
ssl_certificate_key /root/gmtest/server-enc.key;
ssl_certificate /root/gmtest/server-sign.crt;
ssl_certificate_key /root/gmtest/server-sign.key;
location / {
root /usr/local/openresty/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
开启nginx服务
$cd /usr/local/openresty/nginx
#编辑nginx.conf
$vim conf/nginx.conf
#验证并开启nginx
$./sbin/nginx
7. 服务器端验证
https://172.16.150.8