国密证书应用一:使用Tongsuo签发SM2/RSA证书

1,525 阅读6分钟

1. 安装依赖

# Ubuntu
apt-get install  g++  make  autoconf automake pkg-config -y

2. 编译安装Tongsuo

cd /usr/local/src
# 下载Tongsuo
wget -c https://github.com/Tongsuo-Project/Tongsuo/archive/refs/tags/8.4.0.tar.gz

# 解压Tongsuo源码
tar zxf Tongsuo-8.4.0.tar.gz


# 配置选项
./config --prefix=/usr/local/tongsuo -Wl,-rpath,/usr/local/tongsuo/lib enable-ec_elgamal enable-paillier enable-ntls

# 查看 config 结果
perl configdata.pm --dump

# 编译
make -j

# 安装
make install

# 设置环境变量
echo "export PATH=$PATH:/usr/local/tongsuo/bin" >> /root/.bashrc
echo "export LD_LIBRARY_PATH=/usr/local/tongsuo/lib64/" >> /root/.bashrc
source /root/.bashrc

铜锁Tongsuo文档:www.yuque.com/tsdoc/ts 

3. SM2证书

3.1 签发准备

# 创建工作目录
mkdir /opt/sm2Cert_SelfSigned
cd /opt/sm2Cert_SelfSigned

mkdir  ./newcerts
mkdir  ./db
touch db/index
touch db/serial
echo 00 > db/serial

3.2 配置文件

3.2.1 配置文件1

vi /opt/sm2Cert_SelfSigned/ca.cnf

文件内容默认即可。 

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = ./
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/db/index
unique_subject    = no
serial            = $dir/db/serial
RANDFILE          = $dir/private/random

# The root key and root certificate.
private_key       = $dir/ca.key
certificate       = $dir/ca.crt

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sha256

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 365
preserve          = no
policy            = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = optional
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

req_extensions = v3_req

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = optional
stateOrProvinceName             = optional
localityName                    = optional
organizationName                = optional
organizationalUnitName          = optional
commonName                      = optional
emailAddress                    = optional

[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = localhost

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning

3.2.2 配置文件2

vim /opt/sm2Cert_SelfSigned/subca.cnf

根据实际情况,调整 [ alt_names ]内容。

[ ca ]
# `man ca`
default_ca = CA_default

[ CA_default ]
# Directory and file locations.
dir               = ./
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/db/index
unique_subject    = no
serial            = $dir/db/serial
RANDFILE          = $dir/private/random

# The root key and root certificate.
private_key       = $dir/subca.key
certificate       = $dir/subca.crt

# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30

# SHA-1 is deprecated, so use SHA-2 instead.
default_md        = sm3

name_opt          = ca_default
cert_opt          = ca_default
default_days      = 365
preserve          = no
policy            = policy_strict

[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
# See the POLICY FORMAT section of `man ca`.
countryName             = optional
stateOrProvinceName     = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
# See the POLICY FORMAT section of the `ca` man page.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
# Options for the `req` tool (`man req`).
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only

# SHA-1 is deprecated, so use SHA-2 instead.
default_md          = sha256

# Extension to add when the -x509 option is used.
x509_extensions     = v3_ca

req_extensions = v3_req

[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
countryName                     = optional
stateOrProvinceName             = optional
localityName                    = optional
0.organizationName              = optional
organizationalUnitName          = optional
commonName                      = optional
emailAddress                    = optional

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = *.text.cc
IP.1 = 192.168.159.151
IP.2 = 192.168.159.152

[ v3_ca ]
# Extensions for a typical CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (`man x509v3_config`).
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier=keyid:always

[ ocsp ]
# Extension for OCSP signing certificates (`man ocsp`).
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning

[ server_sign_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature
# Add more items here, for instance:
# subjectAltName = @alt_names

[ server_enc_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = keyAgreement, keyEncipherment, dataEncipherment
# Add more items here, for instance:
# subjectAltName = @alt_names

[ client_sign_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature

[ client_enc_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = keyAgreement, keyEncipherment, dataEncipherment

3.3.1 签发根证书

tongsuo genpkey -algorithm ec -pkeyopt ec_paramgen_curve:sm2 -out ca.key

tongsuo req -config ca.cnf -new -key ca.key -out ca.csr -sm3 -nodes -subj "/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=SeeyonCA"

tongsuo ca -selfsign -config ca.cnf -in ca.csr -keyfile ca.key -extensions v3_ca -days 3650 -notext -out ca.crt -md sm3 -batch

3.3.2 签发中间CA

tongsuo genpkey -algorithm ec -pkeyopt ec_paramgen_curve:sm2 -out subca.key

tongsuo req -config ca.cnf -new -key subca.key -out  subca.csr -sm3 -nodes -subj "/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=SeeyonSubCA"

tongsuo ca -config ca.cnf -extensions v3_intermediate_ca -days 3650 -in  subca.csr -notext -out  subca.crt -md sm3 -batch

cat ca.crt  subca.crt > chain-ca.crt

3.3.2 签发服务器证书

1. 签名证书

tongsuo genpkey -algorithm ec -pkeyopt ec_paramgen_curve:sm2 -out server_sign.key

tongsuo req -config subca.cnf -key server_sign.key -new -out  server_sign.csr -sm3 -nodes -subj "/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=ServerSign"

tongsuo ca -config subca.cnf -extensions server_sign_req -days 3650 -in  server_sign.csr -notext -out server_sign.crt -md sm3 -batch

# 证书校验

# 证书内容

2. 加密证书

tongsuo genpkey -algorithm ec -pkeyopt ec_paramgen_curve:sm2 -out server_enc.key

tongsuo req -config subca.cnf -key server_enc.key -new -out  server_enc.csr -sm3 -nodes -subj "/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=ServerEnc"

tongsuo ca -config subca.cnf -extensions server_enc_req -days 3650 -in  server_enc.csr -notext -out server_enc.crt -md sm3 -batch

# 证书校验

# 证书内容

3.3.3 生成 PKCS12 秘钥库

tongsuo pkcs12 -export -inkey server_sign.key -in server_sign.crt -CAfile chain-ca.crt -chain -out server_sign.p12 -password pass:"12345678" -name "sm2.server.sig"

tongsuo pkcs12 -export -inkey server_enc.key -in server_enc.crt -CAfile chain-ca.crt -chain -out server_enc.p12 -password pass:"12345678" -name "sm2.server.enc"

# 证书校验

# 证书内容

3.3.4. 生成JAVA密钥库/信任库

3.4 签发客户端证书

tongsuo genpkey -algorithm ec -pkeyopt ec_paramgen_curve:sm2 -out client_sign.key

tongsuo req -config subca.cnf -key client_sign.key -new -out  client_sign.csr -sm3 -nodes -subj "/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=ClientSign"

tongsuo ca -config subca.cnf -extensions client_sign_req -days 3650 -in  client_sign.csr -notext -out client_sign.crt -md sm3 -batch

tongsuo genpkey -algorithm ec -pkeyopt ec_paramgen_curve:sm2 -out client_enc.key

tongsuo req -config subca.cnf -key client_enc.key -new -out  client_enc.csr -sm3 -nodes -subj "/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=ClientEnc"

tongsuo ca -config subca.cnf -extensions client_enc_req -days 3650 -in  client_enc.csr -notext -out client_enc.crt -md sm3 -batch

 

4. RSA证书

4.1 签发准备

# 创建工作目录
mkdir /opt/rsaCert_SelfSigned
cd /opt/rsaCert_SelfSigned

mkdir -p ./{key,csr,crt}

4.2 配置文件

vi /opt/rsaCert_SelfSigned/v3.ext
[ v3_ca ]
basicConstraints = critical,CA:TRUE
keyUsage = nonRepudiation, digitalSignature, keyCertSign, cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true

[ v3_intermediate_ca ]
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer

[ v3_server ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.wxn.cc
DNS.2 = *.text.cc
IP.1 = 192.168.159.181

4.3 签发

4.3.1 根证书

tongsuo genrsa -des3 -passout pass:12345678 -out ./key/ca.key 2048 

tongsuo req -new -key ./key/ca.key -out ./csr/ca.csr -subj  '/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=ServerCA' -passin pass:12345678

tongsuo x509 -req -in ./csr/ca.csr -signkey ./key/ca.key -out ./crt/ca.crt -outform PEM  -days 3650  -extfile v3.ext -extensions v3_ca -passin pass:12345678

tongsuo ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key  

# 查看创建的证书
tongsuo x509 -in ./crt/ca.crt -text -noout

# 查看CSR详情
tongsuo req -noout -text -in ./csr/ca.csr

4.3.2 中间证书

tongsuo genrsa -des3 -passout pass:12345678  -out ./key/subca.key 2048

tongsuo req -new -key ./key/subca.key -out ./csr/subca.csr -subj  '/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=SeeyonSubCA' -passin pass:12345678

tongsuo x509 -sha256  -CA ./crt/ca.crt -CAkey ./key/ca.key -CAcreateserial -req -in ./csr/subca.csr -out ./crt/subca.crt  -outform PEM -days 3650 -extfile v3.ext -extensions v3_intermediate_ca -passin pass:12345678

# 查看创建的证书
tongsuo x509 -in ./crt/subca.crt -text -noout

# 验证证书
tongsuo verify -CAfile ./crt/ca.crt ./crt/subca.crt
# 合成证书链
# server.crt的签发是subca,而subca的签发是ca
# 对server.crt的验证必须使用到这两个证书,需要制作为证书链。
# 制作证书链的方法直白而简单:将证书拼接在一个文件中即可
cat ./crt/subca.crt ./crt/ca.crt  > ./crt/chain-ca.crt

4.3.3 服务器证书

tongsuo genrsa -des3 -passout pass:12345678 -out ./key/server.key 2048 

tongsuo req -new -key ./key/server.key -out ./csr/server.csr -subj  '/C=CN/ST=SHAANXI/O=Seeyon/OU=Gov/CN=ServerRsa' -passin pass:12345678

tongsuo x509 -req -sha256  -CA ./crt/subca.crt -CAkey ./key/subca.key  -in ./csr/server.csr -out ./crt/server.crt  -outform PEM  -CAserial serial -days 3650 -extfile v3.ext -extensions v3_server  -passin pass:12345678
 
# 查看创建的证书
tongsuo x509 -in ./crt/server.crt -text -noout

# 证书链验证server证书
tongsuo verify -CAfile ./crt/chain-ca.crt ./crt/server.crt

4.3.4 生成 PKCS12 秘钥库

# 其中-export指导出pkcs#12 证书,-inkey 指定了私钥文件,-passin 为私钥(文件)密码(nodes为无加密),-password 指定 p12文件的密码(导入导出)
tongsuo pkcs12 -export -in ./crt/server.crt -inkey ./key/server.key -chain -CAfile ./crt/chain-ca.crt -name rsa.wxn.cc -out ./crt/server.p12 -password pass:12345678 -passin pass:12345678

# 查看生成的p12文件
tongsuo pkcs12 -in ./crt/server.p12 -password pass:12345678  

# 只查看私钥
tongsuo pkcs12 -in ./crt/server.p12 -nocerts -nodes -password pass:12345678

# 只查证书(非CA证书)
tongsuo pkcs12 -in ./crt/server.p12 -clcerts -nokeys -password pass:12345678

# 只查看CA证书
tongsuo pkcs12 -in ./crt/server.p12 -cacerts -nokeys -chain -password pass:12345678

 

4.3.5 转化为keystore文件

# 将server.p12转化为server.jks[扩展名可以为 pfx,p12] [同时包含服务器私钥、服务器证书、中间CA、根CA]
keytool -importkeystore -destkeystore ./crt/server.jks -deststoretype pkcs12  -deststorepass 12345678   -srckeystore ./crt/server.p12 -srcstoretype PKCS12 -srcstorepass 12345678 -noprompt

# 查看keystore文件
keytool -list -v -keystore ./crt/server.jks -v -storepass 12345678

# 查看keystore文件 (rfc 格式)
keytool -list -rfc -keystore ./crt/server.jks -storepass 12345678

5. 附

国密SSL实验室(提供国密SSL相关软件/工具/服务):www.gmssl.cn/
国密证书实验室(签发SM2/ECC/RSA证书):www.gmcrt.cn/
测试SSL证书生成:myssl.com/create_test…
证书格式转换:myssl.com/cert_conver…