GmSSL开发环境搭建及双证书生成

国密开发总结

国密开发环境搭建及双证书生成

GMSSL

GmSSL是一个开放源代码加密工具包,它提供对GM / T串行标准中指定的中国国家加密算法和协议的第一级支持。作为OpenSSL项目的一个分支,GmSSL提供与OpenSSL的API级别兼容性并维护所有功能。在此感谢贡献,该项目地址:(https://github.com/guanzhi/GmSSL)

1. 代码下载及配置变量

# 通过git下载
$ git clone https://github.com/guanzhi/GmSSL gmssl
# 如果嫌下载速度慢,也可下载代码压缩包
$ wget https://github.com/guanzhi/GmSSL/archive/master.zip
$ unzip master.zip

GmSSL工具箱相关项目文档

2. 编译与安装

$ cd 你解压的目录
$ ./config --prefix=/usr/local/gmssl
$ make
$ make install
$ cd /usr/local/gmssl
# tree:显示目录树 -d:只显示目录 -L:选择显示的目录深度 /usr/local/gmssl目录树如下
$ tree -L 2
.
|-- bin
|   |-- c_rehash
|   |-- gmssl
|   `-- openssl -> gmssl
|-- include
|   `-- openssl
|-- lib
|   |-- engines-1.1
|   |-- libcrypto.a
|   |-- libcrypto.so -> libcrypto.so.1.1
|   |-- libcrypto.so.1.1
|   |-- libssl.a
|   |-- libssl.so -> libssl.so.1.1
|   |-- libssl.so.1.1
|   `-- pkgconfig
|-- share
|   |-- doc
|   `-- man
`-- ssl
    |-- certs
    |-- misc
    |-- openssl.cnf
    |-- openssl.cnf.dist
    `-- private
  • config貌似动态编译、静态编译也会有一定的影响,(no-shared 不去编译动态库,编译出来的 gmssl不再依赖 libssl.so ,避免因缺少动态库出错)这块我也不是很了解,等日后我有了提升再来说说。

  • openssl.cnf位于/usr/local/gmssl/ssl下,可以按需修改生成各种文件位置、信息等等,需要注意的是生成证书、私钥的位置、名称要与openssl中保持一致。
    3. 配置环境变量及检测

如果不配置,就会出现找不到gmssl命令的情况

# 配置安装路径 在已有的PATH等变量前面添加路径‘:’号为分隔符,这种只是临时生效,关闭shell即失效
PATH=/usr/local/gmssl/bin:$PATH
LD_LIBRARY_PATH=/usr/local/gmssl/lib:$LD_LIBRARY_PATH
  • 在/etc/profile文件中添加变量对所有用户生效(永久的)
vim /etc/profile
#编辑
export PATH=/usr/local/gmssl/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/gmssl/lib:$LD_LIBRARY_PATH
source /etc/profile

4.初始化目录

这是我openssl.cnf的部分配置,详细配置可以参考

OpenSSL主配置文件

# 创建根目录
mkdir -p /home/gmssl/demoCA
cd /home/gmssl/demoCA
mkdir certs crl newcerts private
# 在此路径下要创建好/usr/local/gmssl/ssl/openssl.cnf中需要的certs, crl ,new_certs_dir和private_key的子目录,默认是newcerts和private
touch index.txt
echo '01' > serial

5.生成国密证书

  • 生成根证书
# 生成 私钥key
gmssl ecparam -genkey -name sm2p256v1 -text -out CA.key -config  /usr/local/gmssl/ssl/openssl.cnf 
# 生成证书签名请求
gmssl req -new -key CA.key -out Root.req 
# 生成根证书
gmssl x509 -req -days 3650 -sm3 -in Root.req -signkey Root.key -out RootCA.crt
  • 生成服务端证书
# 生成私钥
gmssl ecparam -genkey -name sm2p256v1 -text -out Server.key
#证书项说明
C-----国家(Country Name)
ST----省份(State or Province Name)
L----城市(Locality Name)
O----公司(Organization Name)
OU----部门(Organizational Unit Name)
CN----产品名(Common Name)
emailAddress----邮箱(Email Address)
#证书请求
gmssl req -new -key Server.key -out Server.csr -subj /C=CN/ST=Beijing/L=Beijing/O=CSG/OU=WangAn (GM)/CN=*.vpn.test.cn -config /usr/local/gmssl/ssl/openssl.cnf
#签发证书
gmssl x509 -req -sm3 -days 3650 -CA RootCA.crt -CAkey Root.key -CAcreateserial -in Server.req -out ServerCA.crt
# 证书验证
gmssl verify -CAfile RootCA.crt ServerCA.crt
.crt ServerCA.crt
ServerCA.crt: OK
$ tree
.
|-- certs
|-- crl
|-- index.txt
|-- newcerts
|-- private
|   `-- Root.key
|-- RootCA.crt
|-- RootCA.srl
|-- Root.key
|-- Root.req
|-- serial
|-- ServerCA.crt
|-- Server.csr
`-- Server.key

  • 生成客户端证书
# 生成私钥
gmssl ecparam -genkey -name sm2p256v1 -text -out Client.key -config /usr/local/gmssl/ssl/openssl.cnf 
# 生成客户证书请求
gmssl req -new -key Client.key -out Client.req -subj /C=CN/ST=Beijing/L=Beijing/O=CSG/OU=WangAn (GM)/CN=*.vpn.test.cn  -config  /usr/local/gmssl/ssl/openssl.cnf
# 签发证书
gmssl x509 -req -sm3 -days 3650 -CA  RootCA.crt -CAkey demoCA/private/Root.key -CAcreateserial -in Client.req -out Client.crt 
# 证书验证
gmssl verify -CAfile RootCA.crt Client.crt 

6.生成脚本

不过像我这种懒人,上面仅限于学习明白过程即可,实际中是不会这样干的。

#!/bin/sh
# gen GM certificate files
CurPath=`dirname $(readlink -f $0)`
 
GmsslRootPath=/usr/local/gmssl
LdPath=/usr/local/gmssl/lib
GmsslBin=gmssl
DemoCaDir=${GmsslRootPath}/apps/demoCA/
CertDir=${DemoCaDir}/certs/
KeyDir=${CertDir}/keys/
CrlDir=${DemoCaDir}/crl/
ReqDir=${DemoCaDir}/reqs/
 
CertDays=1500
 
CACertFile=CA.cert.pem
CAKeyFile=CA.key.pem
CA_DN_STRING=" /C=CN/ST=Beijing/L=Beijing/O=CSG/OU=WangAn (GM)/CN=*.vpn.test.cn"
CAReqFile=CA.req
 
SSCertFile=SS.cert.pem
SSKeyFile=SS.key.pem
SS_DN_STRING=" /C=CN/ST=Beijing/L=Beijing/O=CSG/OU=WangAn (GM)/CN=*.vpn.test.cn"
SSReqFile=SS.req
 
SECertFile=SE.cert.pem
SEKeyFile=SE.key.pem
SE_DN_STRING=" /C=CN/ST=Beijing/L=Beijing/O=CSG/OU=WangAn (GM)/CN=*.vpn.test.cn"
SEReqFile=SE.req
 
CSCertFile=CS.cert.pem
CSKeyFile=CS.key.pem
CS_DN_STRING=" /C=CN/ST=Beijing/L=Beijing/O=CSG/OU=vpn.test.cn/CN=WangAn (GM)"
CSReqFile=CS.req
 
CECertFile=CE.cert.pem
CEKeyFile=CE.key.pem
CE_DN_STRING=" /C=CN/ST=Beijing/L=Beijing/O=CSG/OU=WangAn (GM)/CN=*.vpn.test.cn"
CEReqFile=CE.req
 
if [ ! -d "${GmsslRootPath}" ];then
    echo "GmSSL path DONOT exist!"
    exit 2
fi
 
export LD_LIBRARY_PATH=${LdPath}
 
rm -rf "${GmsslRootPath}/apps/demoCA/"
mkdir -p "${CertDir}"
mkdir -p "${KeyDir}"
mkdir -p "${CrlDir}"
mkdir -p "${ReqDir}"
 
echo "#######################################################################################################"
echo "Generate CA certificate file..."
${GmsslBin} ecparam -name sm2p256v1 -out "${DemoCaDir}/SM2.pem"
${GmsslBin} req -config "${GmsslRootPath}/apps/openssl.cnf" -nodes -subj "${CA_DN_STRING}" \
    -keyout "${KeyDir}/${CAKeyFile}" -newkey "ec:${DemoCaDir}/SM2.pem" \
    -new -out "${ReqDir}/${CAReqFile}"
 
#Sign CA certificate with CAKeyFile
${GmsslBin} x509 -sm3 -req -days ${CertDays} -in "${ReqDir}/${CAReqFile}" \
    -extfile "${GmsslRootPath}/apps/openssl.cnf" -extensions v3_ca -signkey "${KeyDir}/${CAKeyFile}" \
    -CAcreateserial -out "${CertDir}/${CACertFile}"
 
#Print CA certificate file
${GmsslBin} x509 -in "${CertDir}/${CACertFile}" -noout -text
 
echo "#######################################################################################################"
echo "Generate Server sign certificate file..."
${GmsslBin} req -config "${GmsslRootPath}/apps/openssl.cnf" -nodes -subj "${SS_DN_STRING}" \
    -keyout "${KeyDir}/${SSKeyFile}" -newkey "ec:${DemoCaDir}/SM2.pem" \
    -new -out "${ReqDir}/${SSReqFile}"
 
#Sign SS certificate with CAKeyFile
${GmsslBin} x509 -sm3 -req -days ${CertDays} -in "${ReqDir}/${SSReqFile}" \
    -CA "${CertDir}/${CACertFile}" -CAkey "${KeyDir}/${CAKeyFile}" \
    -extfile "${GmsslRootPath}/apps/openssl.cnf" -extensions v3_req \
    -CAcreateserial -out "${CertDir}/${SSCertFile}"
 
#Print SS certificate file
${GmsslBin} x509 -in "${CertDir}/${SSCertFile}" -noout -text
 
echo "#######################################################################################################"
echo "Generate Server encrypt certificate file..."
${GmsslBin} req -config "${GmsslRootPath}/apps/openssl.cnf" -nodes -subj "${SE_DN_STRING}" \
    -keyout "${KeyDir}/${SEKeyFile}" -newkey "ec:${DemoCaDir}/SM2.pem" \
    -new -out "${ReqDir}/${SEReqFile}"
 
#Sign SE certificate with CAKeyFile
${GmsslBin} x509 -sm3 -req -days ${CertDays} -in "${ReqDir}/${SEReqFile}" \
    -CA "${CertDir}/${CACertFile}" -CAkey "${KeyDir}/${CAKeyFile}" \
    -extfile "${GmsslRootPath}/apps/openssl.cnf" -extensions v3_req\
    -CAcreateserial -out "${CertDir}/${SECertFile}"
 
#Print SE certificate file
${GmsslBin} x509 -in "${CertDir}/${SECertFile}" -noout -text
 
echo "#######################################################################################################"
echo "Generate Client sign certificate file..."
${GmsslBin} req -config "${GmsslRootPath}/apps/openssl.cnf" -nodes -subj "${CS_DN_STRING}" \
    -keyout "${KeyDir}/${CSKeyFile}" -newkey "ec:${DemoCaDir}/SM2.pem" \
    -new -out "${ReqDir}/${CSReqFile}"
 
#Sign CS certificate with CAKeyFile
${GmsslBin} x509 -sm3 -req -days ${CertDays} -in "${ReqDir}/${CSReqFile}" \
    -CA "${CertDir}/${CACertFile}" -CAkey "${KeyDir}/${CAKeyFile}" \
    -extfile "${GmsslRootPath}/apps/openssl.cnf" -extensions v3_req \
    -CAcreateserial -out "${CertDir}/${CSCertFile}"
 
#Print CS certificate file
${GmsslBin} x509 -in "${CertDir}/${CSCertFile}" -noout -text
 
echo "#######################################################################################################"
echo "Generate Client encrypt certificate file..."
${GmsslBin} req -config "${GmsslRootPath}/apps/openssl.cnf" -nodes -subj "${CE_DN_STRING}" \
    -keyout "${KeyDir}/${CEKeyFile}" -newkey "ec:${DemoCaDir}/SM2.pem" \
    -new -out "${ReqDir}/${CEReqFile}"
 
#Sign CE certificate with CAKeyFile
${GmsslBin} x509 -sm3 -req -days ${CertDays} -in "${ReqDir}/${CEReqFile}" \
    -CA "${CertDir}/${CACertFile}" -CAkey "${KeyDir}/${CAKeyFile}" \
    -extfile "${GmsslRootPath}/apps/openssl.cnf" -extensions v3_req\
    -CAcreateserial -out "${CertDir}/${CECertFile}"
 
#Print CE certificate file
${GmsslBin} x509 -in "${CertDir}/${CECertFile}" -noout -text

每次demoCA目录结构都会删除重新创建,下面是/usr/local/gmssl/apps下的目录结构:

$ tree -L 4
.
|-- demoCA
|   |-- certs
|   |   |-- CA.cert.pem
|   |   |-- CA.srl
|   |   |-- CE.cert.pem
|   |   |-- CS.cert.pem
|   |   |-- keys
|   |   |   |-- CA.key.pem
|   |   |   |-- CE.key.pem
|   |   |   |-- CS.key.pem
|   |   |   |-- SE.key.pem
|   |   |   `-- SS.key.pem
|   |   |-- SE.cert.pem
|   |   `-- SS.cert.pem
|   |-- crl
|   |-- reqs
|   |   |-- CA.req
|   |   |-- CE.req
|   |   |-- CS.req
|   |   |-- SE.req
|   |   `-- SS.req
|   `-- SM2.pem
`-- openssl.cnf


7.生成证书注销列表

脚本代码:

#certificate crl file
CurPath=`dirname $(readlink -f $0)`
 
GmsslRootPath=/usr/local/gmssl
GmsslBin=gmssl
DemoCaDir=${GmsslRootPath}/apps/demoCA
CertDir=${DemoCaDir}/certs
KeyDir=${CertDir}/keys
CrlDir=${DemoCaDir}/crl
ReqDir=${DemoCaDir}/reqs/
 
if [ -z "$1" ]; then
	echo "Usage: "`basename "$0"`" cert0 [cert1 cert2 ...]"
fi
 
touch "${DemoCaDir}/index.txt"
touch "${DemoCaDir}/index.txt.attr"
if [ ! -e "${DemoCaDir}/crlnumber" ]; then
	echo 01 > "${DemoCaDir}/crlnumber"
fi
 
cd "${DemoCaDir}/.."
 
until [ $# -eq 0 ]
do
	${GmsslBin} ca -revoke "${CertDir}/$1" -keyfile "${KeyDir}/CA.key.pem" -cert "${CertDir}/CA.cert.pem"
	shift
done
${GmsslBin} ca -gencrl -keyfile "${KeyDir}/CA.key.pem" -cert "${CertDir}/CA.cert.pem" -out "${CrlDir}/gm_cert.crl"

生成之后/usr/local/gmssl/apps的目录:

$ tree
.
|-- demoCA
|   |-- certs
|   |   |-- CA.cert.pem
|   |   |-- CA.srl
|   |   |-- CE.cert.pem
|   |   |-- CS.cert.pem
|   |   |-- keys
|   |   |   |-- CA.key.pem
|   |   |   |-- CE.key.pem
|   |   |   |-- CS.key.pem
|   |   |   |-- SE.key.pem
|   |   |   `-- SS.key.pem
|   |   |-- SE.cert.pem
|   |   `-- SS.cert.pem
|   |-- crl
|   |   `-- gm_cert.crl
|   |-- crlnumber
|   |-- crlnumber.old
|   |-- index.txt
|   |-- index.txt.attr
|   |-- reqs
|   |   |-- CA.req
|   |   |-- CE.req
|   |   |-- CS.req
|   |   |-- SE.req
|   |   `-- SS.req
|   `-- SM2.pem
`-- openssl.cnf

posted @ 2020-09-06 01:21  巴山夜雨时☂☂☂  阅读(3030)  评论(0编辑  收藏  举报