本文使用OpenSSL工具生成国密算法SM2的三级CA证书,组成证书链,并使用证书链签名客户端证书和服务端证书。

可以通过证书链对生成的客户端和服务端证书进行校验。

虽然OpenSSL工具可以使用SM2算法来生成并校验证书,但是在TLS握手过程中主要支持RSA和ECC算法作为公钥加密算法,不支持SM2算法,因此无法在TLS加密连接中使用SM2证书。

SSL/TLS协议主要使用RSA和ECC(椭圆曲线密码学)算法作为公钥加密算法,而SM2算法属于ECC算法的一种。RFC8898

OpenSSL配置

openssl.cnf配置文件节选内容如下:

####################################################################
[ ca ]
default_ca      = CA_default            # The default ca section

####################################################################
[ CA_default ]
# 默认CA配置

dir             = /home/xxx/CA                  # Where everything is kept 存放CA相关信息的总目录
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/rootca.pem               # The CA certificate CA的自签名证书
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/rootkey.pem      # The private key CA私钥
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      = default               # 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

# 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

在生成证书之前需要用上面的配置覆盖系统中openssl.cnf文件中的相关配置

RootCA

根CA证书生成脚本gen_rootca.sh脚本内容如下:

#!/bin/bash

# 创建相关目录
if ! mkdir -p "$HOME"/CA/{cert,crl,newcerts,private} ;
then
    echo "mkdir failed"
    exit 1
fi

# # cd失败立即退出
cd "$HOME/CA" || { echo "cd $HOME/CA failed and remove $HOME/CA and exit 1"; rm -rf "$HOME"/CA; exit 1; }

# ~/CA中执行以下命令
if ! touch index.txt;
then
    echo "touch index.txt and remove $HOME/CA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/CA;
    exit 1;
fi
#
if ! echo 01 > serial;
then
    echo "echo 01 > serial failed and remove $HOME/CA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/CA;
    exit 1;
fi

#
# 定义相关变量
#
C=CN            # 国家
ST=SH           # 省份
L=XA            # 城市
O=demo          # 组织
OU=demo         # 部门
CN=rootca       # 通用名
email=rootca@test.com       # 邮箱
RootKey=private/rootkey.pem # 生成的RootCA私钥
RootCA=rootca.pem           # pem格式的RootCA证书
RootCACert=rootca.crt       # crt格式的RootCA证书

# 生成根证书SM2私钥
if ! openssl ecparam -genkey -name SM2 -param_enc explicit -outform pem -out "$RootKey";
then
    echo "generate SM2 root private key failed and remove $HOME/CA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/CA;
    exit 1;
fi
#
# 使用SM2私钥创建根CA证书
if ! openssl req -new -x509 -key private/rootkey.pem -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN/emailAddress=$email" -days 3650 -config "$HOME"/openssl.cnf -out "$RootCA";
then
    echo "generate SM2 root ca file failed and remove $HOME/CA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/CA;
    exit 1;
fi
#
# pem格式证书转为crt
if ! openssl x509 -in "$RootCA" -out "$RootCACert";
then
    echo "pem convert to crt failed and remove $HOME/CA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/CA;
    exit 1;
fi

echo "-----------------------------------------------------------------"
echo "~$ tree"
tree

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -noout -text -in $RootCACert"
openssl x509 -in "$RootCACert" -noout -text

RootCA生成结果如下:

~$ ./gen_rootca.sh
-----------------------------------------------------------------
~$ tree
.
├── cert
├── crl
├── index.txt
├── newcerts
├── private
│   └── rootkey.pem
├── rootca.crt
├── rootca.pem
└── serial

5 directories, 5 files
-----------------------------------------------------------------
~$ openssl x509 -noout -text -in rootca.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            72:8c:11:8a:e1:b7:31:8c:89:6c:15:ed:20:e0:46:9e:2a:cc:11:6c
        Signature Algorithm: SM2-with-SM3
        Issuer: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = rootca, emailAddress = rootca@test.com
        Validity
            Not Before: Apr 13 03:21:31 2024 GMT
            Not After : Apr 11 03:21:31 2034 GMT
        Subject: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = rootca, emailAddress = rootca@test.com
        Subject Public Key Info:
            Public Key Algorithm: sm2
                Public-Key: (256 bit)
                pub:
                    04:e8:a5:b3:e1:b6:7a:bd:ce:af:74:2b:7a:04:46:
                    05:99:fd:e3:8b:88:2e:0d:80:48:b3:42:9d:a4:3d:
                    8f:fa:22:e5:42:a7:a1:be:e2:98:2c:5a:67:2b:38:
                    9d:5b:c2:e2:78:21:eb:23:bb:2f:f0:49:da:5a:16:
                    36:ee:d5:f3:ef
                Field Type: prime-field
                Prime:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:ff
                A:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:fc
                B:
                    28:e9:fa:9e:9d:9f:5e:34:4d:5a:9e:4b:cf:65:09:
                    a7:f3:97:89:f5:15:ab:8f:92:dd:bc:bd:41:4d:94:
                    0e:93
                Generator (uncompressed):
                    04:32:c4:ae:2c:1f:19:81:19:5f:99:04:46:6a:39:
                    c9:94:8f:e3:0b:bf:f2:66:0b:e1:71:5a:45:89:33:
                    4c:74:c7:bc:37:36:a2:f4:f6:77:9c:59:bd:ce:e3:
                    6b:69:21:53:d0:a9:87:7c:c6:2a:47:40:02:df:32:
                    e5:21:39:f0:a0
                Order:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:72:03:df:6b:21:c6:05:2b:53:bb:f4:09:39:
                    d5:41:23
                Cofactor:  1 (0x1)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                90:A4:1B:E5:A6:15:C3:C3:6D:BC:BA:23:12:28:54:18:90:C9:52:81
            X509v3 Authority Key Identifier:
                90:A4:1B:E5:A6:15:C3:C3:6D:BC:BA:23:12:28:54:18:90:C9:52:81
            X509v3 Basic Constraints: critical
                CA:TRUE # 这里表明该证书可用于签名其他证书
    Signature Algorithm: SM2-with-SM3
    Signature Value:
        30:45:02:21:00:da:c3:8a:49:bd:34:21:7a:23:95:84:ca:9e:
        59:87:83:d4:15:0b:b7:ba:3b:6b:7d:ba:0b:a5:ab:55:05:44:
        d9:02:20:14:46:09:44:57:b0:90:f2:e2:67:18:d8:bc:a5:c7:
        14:f5:cc:b8:e6:ad:35:32:f4:3a:52:48:ab:35:96:50:36

二级CA

二级CA证书生成脚本gen_secondca.sh内容如下:

#!/bin/bash

# 创建相关目录
if ! mkdir -p "$HOME"/SecondCA ;
then
    echo "mkdir failed"
    exit 1
fi

# # cd失败立即退出
cd "$HOME/SecondCA" || { echo "cd $HOME/SecondCA failed and remove $HOME/SecondCA and exit 1"; rm -rf "$HOME"/SecondCA ; exit 1; }

# ~/SecondCA 中执行以下命令
#
# 定义相关变量
#
C=CN            # 国家
ST=SH           # 省份
L=XA            # 城市
O=demo          # 组织
OU=demo         # 部门
CN=secondca     # 通用名
email=secondca@test.com     # 邮箱
SecondKey=secondkey.pem     # 生成的SecondCA私钥
SecondCSR=secondca.csr      # 生成证书的签名请求文件
SecondCA=secondca.pem       # pem格式的SecondCA证书
SecondCACert=secondca.crt   # crt格式的SecondCA证书

if ! echo 02 > "$HOME"/CA/serial;
then
    echo "echo 02 > $HOME/CA/serial failed and remove $HOME/SecondCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/SecondCA ;
    exit 1;
fi

# 生成二级证书SM2私钥
if ! openssl ecparam -genkey -name SM2 -param_enc explicit -outform pem -out "$SecondKey";
then
    echo "generate SM2 secondca private key failed and remove $HOME/SecondCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/SecondCA ;
    exit 1;
fi
#
# 使用SM2私钥创建签名请求
if ! openssl req -new -key "$SecondKey" -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN/emailAddress=$email" -config "$HOME"/openssl.cnf -out "$SecondCSR";
then
    echo "generate SM2 secondca csr failed failed and remove $HOME/SecondCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/SecondCA ;
    exit 1;
fi

# 使用根CA证书进行签名,这里不显示指定根证书的原因在于openssl.cnf中已经设置
if ! openssl ca -extensions v3_ca -in "$SecondCSR" -days 3650 -config "$HOME"/openssl.cnf -out "$SecondCA";
then
    echo "generate SM2 secondca certificate failed failed and remove $HOME/SecondCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/SecondCA ;
    exit 1;
fi

# pem格式证书转为crt
if ! openssl x509 -in "$SecondCA" -out "$SecondCACert";
then
    echo "pem convert to crt failed and remove $HOME/SecondCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/SecondCA ;
    exit 1;
fi

echo "-----------------------------------------------------------------"
echo "~$ tree"
tree

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $HOME/CA/rootca.crt $SecondCA"
openssl verify -verbose -CAfile "$HOME"/CA/rootca.crt "$SecondCA"

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $HOME/CA/rootca.crt $SecondCACert"
openssl verify -verbose -CAfile "$HOME"/CA/rootca.crt "$SecondCACert"

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -in secondca.crt -noout -dates"
openssl x509 -in secondca.crt -noout -dates

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -noout -text -in secondca.crt"
openssl x509 -noout -text -in secondca.crt

生成结果如下:

~$ ./gen_secondca.sh
Using configuration from /home/xxx/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Apr 13 03:22:00 2024 GMT
            Not After : Apr 11 03:22:00 2034 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = SH
            localityName              = XA
            organizationName          = demo
            organizationalUnitName    = demo
            commonName                = secondca
            emailAddress              = secondca@test.com
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                00:5F:38:E1:B9:68:22:D4:01:6B:FC:68:A3:56:58:7A:19:88:66:3C
            X509v3 Authority Key Identifier:
                90:A4:1B:E5:A6:15:C3:C3:6D:BC:BA:23:12:28:54:18:90:C9:52:81
            X509v3 Basic Constraints: critical
                CA:TRUE
Certificate is to be certified until Apr 11 03:22:00 2034 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Database updated
-----------------------------------------------------------------
~$ tree
.
├── secondca.crt
├── secondca.csr
├── secondca.pem
└── secondkey.pem

1 directory, 4 files
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile /home/xxx/CA/rootca.crt secondca.pem
secondca.pem: OK
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile /home/xxx/CA/rootca.crt secondca.crt
secondca.crt: OK
-----------------------------------------------------------------
~$ openssl x509 -in secondca.crt -noout -dates
notBefore=Apr 13 03:22:00 2024 GMT
notAfter=Apr 11 03:22:00 2034 GMT
-----------------------------------------------------------------
~$ openssl x509 -noout -text -in secondca.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
        Signature Algorithm: SM2-with-SM3
        Issuer: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = rootca, emailAddress = rootca@test.com
        Validity
            Not Before: Apr 13 03:22:00 2024 GMT
            Not After : Apr 11 03:22:00 2034 GMT
        Subject: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = secondca, emailAddress = secondca@test.com
        Subject Public Key Info:
            Public Key Algorithm: sm2
                Public-Key: (256 bit)
                pub:
                    04:cb:e5:cd:7d:d1:92:39:62:94:b0:32:b7:d6:51:
                    35:31:78:5b:76:93:e5:33:78:e3:23:7c:bc:67:77:
                    35:02:25:65:d9:2b:89:ce:81:bf:8a:b3:b6:4b:a9:
                    9b:71:74:58:c7:0f:ba:8a:03:c0:1a:2d:50:34:f4:
                    c8:17:d3:20:a4
                Field Type: prime-field
                Prime:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:ff
                A:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:fc
                B:
                    28:e9:fa:9e:9d:9f:5e:34:4d:5a:9e:4b:cf:65:09:
                    a7:f3:97:89:f5:15:ab:8f:92:dd:bc:bd:41:4d:94:
                    0e:93
                Generator (uncompressed):
                    04:32:c4:ae:2c:1f:19:81:19:5f:99:04:46:6a:39:
                    c9:94:8f:e3:0b:bf:f2:66:0b:e1:71:5a:45:89:33:
                    4c:74:c7:bc:37:36:a2:f4:f6:77:9c:59:bd:ce:e3:
                    6b:69:21:53:d0:a9:87:7c:c6:2a:47:40:02:df:32:
                    e5:21:39:f0:a0
                Order:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:72:03:df:6b:21:c6:05:2b:53:bb:f4:09:39:
                    d5:41:23
                Cofactor:  1 (0x1)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                00:5F:38:E1:B9:68:22:D4:01:6B:FC:68:A3:56:58:7A:19:88:66:3C
            X509v3 Authority Key Identifier:
                90:A4:1B:E5:A6:15:C3:C3:6D:BC:BA:23:12:28:54:18:90:C9:52:81
            X509v3 Basic Constraints: critical
                CA:TRUE # 这里表明该证书可用于签名其他证书
    Signature Algorithm: SM2-with-SM3
    Signature Value:
        30:45:02:21:00:ce:e5:9e:cb:e0:8d:5b:a8:ff:75:7f:87:15:
        7e:4c:3a:8d:9d:45:bb:1c:32:8f:14:4b:79:1d:e5:70:9e:3e:
        bb:02:20:7b:4e:ab:fd:b8:79:74:fb:d1:a9:9c:d7:cc:d1:66:
        cf:5b:c8:aa:0f:e4:de:0c:a3:62:39:f6:f9:72:66:5b:0a

三级CA

三级CA证书生成脚本gen_thirdca.sh内容如下:

#!/bin/bash

# 创建相关目录
if ! mkdir -p "$HOME"/ThirdCA ;
then
    echo "mkdir failed"
    exit 1
fi

# # cd失败立即退出
cd "$HOME/ThirdCA" || { echo "cd $HOME/ThirdCA failed and remove $HOME/ThirdCA and exit 1"; rm -rf "$HOME"/ThirdCA ; exit 1; }

# ~/ThirdCA 中执行以下命令
#
# 定义相关变量
#
C=CN            # 国家
ST=SH           # 省份
L=XA            # 城市
O=demo          # 组织
OU=demo         # 部门
CN=thirdca              # 通用名
email=thirdca@test.com  # 邮箱
ThirdKey=thirdkey.pem   # 生成的三级CA私钥
ThirdCSR=thirdca.csr    # 三级CA证书的签名请求文件
ThirdCA=thirdca.pem     # pem格式的三级CA证书
ThirdCACert=thirdca.crt # crt格式的三级CA证书
SignCert="$HOME"/SecondCA/secondca.crt  # 签名证书
SignKey="$HOME"/SecondCA/secondkey.pem  # 签名私钥
ChainCert=ca-chain.crt                  # 证书链
#
# 生成三级证书SM2私钥
if ! openssl ecparam -genkey -name SM2 -param_enc explicit -outform pem -out "$ThirdKey";
then
    echo "generate SM2 thirdca private key failed and remove $HOME/ThirdCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/ThirdCA ;
    exit 1;
fi
#
# 使用SM2私钥创建签名请求
if ! openssl req -new -key "$ThirdKey" -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN/emailAddress=$email" -config "$HOME"/openssl.cnf -out "$ThirdCSR";
then
    echo "generate SM2 thirdca csr failed failed and remove $HOME/ThirdCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/ThirdCA ;
    exit 1;
fi

# 使用二级CA进行签名,这里要指定签名的证书与私钥
if [ ! -f "$SignKey" ] || [ ! -f "$SignCert" ];
then
    echo "$SignKey or $SignCert doesn't exist and remove $HOME/ThirdCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/ThirdCA ;
    exit 1;
fi
if ! openssl ca -extensions v3_ca -in "$ThirdCSR" -cert "$SignCert" -keyfile "$SignKey" -days 3650 -config "$HOME"/openssl.cnf -out "$ThirdCA";
then
    echo "generate SM2 thirdca certificate failed failed and remove $HOME/ThirdCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/ThirdCA ;
    exit 1;
fi

# pem格式证书转为crt
if ! openssl x509 -in "$ThirdCA" -out "$ThirdCACert";
then
    echo "pem convert to crt failed and remove $HOME/ThirdCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/ThirdCA ;
    exit 1;
fi

# 将根证书与二级证书合并为证书链

echo "-----------------------------------------------------------------"
echo "~$ cat $SignCert $HOME/CA/rootca.crt > $ChainCert"
if ! cat "$SignCert" "$HOME"/CA/rootca.crt > ca-chain.crt;
then
    echo "generate cert chain file failed and remove $HOME/ThirdCA and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/ThirdCA ;
    exit 1;
fi

echo "-----------------------------------------------------------------"
echo "~$ tree"
tree

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $ChainCert $ThirdCA"
openssl verify -verbose -CAfile "$ChainCert" "$ThirdCA"

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $ChainCert $ThirdCACert"
openssl verify -verbose -CAfile "$ChainCert" "$ThirdCACert"

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -in thirdca.crt -noout -dates"
openssl x509 -in thirdca.crt -noout -dates

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -noout -text -in thirdca.crt"
openssl x509 -noout -text -in thirdca.crt

三级CA生成结果如下:

~$ ./gen_thirdca.sh
Using configuration from /home/xxx/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 3 (0x3)
        Validity
            Not Before: Apr 13 03:23:10 2024 GMT
            Not After : Apr 11 03:23:10 2034 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = SH
            localityName              = XA
            organizationName          = demo
            organizationalUnitName    = demo
            commonName                = thirdca
            emailAddress              = thirdca@test.com
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                C1:0D:90:4B:C2:CF:9A:64:48:D7:C5:92:F6:B9:AB:73:95:A1:74:9A
            X509v3 Authority Key Identifier:
                00:5F:38:E1:B9:68:22:D4:01:6B:FC:68:A3:56:58:7A:19:88:66:3C
            X509v3 Basic Constraints: critical
                CA:TRUE
Certificate is to be certified until Apr 11 03:23:10 2034 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Database updated
-----------------------------------------------------------------
~$ cat /home/xxx/SecondCA/secondca.crt /home/xxx/CA/rootca.crt > ca-chain.crt
-----------------------------------------------------------------
~$ tree
.
├── ca-chain.crt # 和并生成证书链文件
├── thirdca.crt
├── thirdca.csr
├── thirdca.pem
└── thirdkey.pem

1 directory, 5 files
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile ca-chain.crt thirdca.pem
thirdca.pem: OK
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile ca-chain.crt thirdca.crt
thirdca.crt: OK
-----------------------------------------------------------------
~$ openssl x509 -in thirdca.crt -noout -dates
notBefore=Apr 13 03:23:10 2024 GMT
notAfter=Apr 11 03:23:10 2034 GMT
-----------------------------------------------------------------
~$ openssl x509 -noout -text -in thirdca.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 3 (0x3)
        Signature Algorithm: SM2-with-SM3
        Issuer: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = secondca, emailAddress = secondca@test.com
        Validity
            Not Before: Apr 13 03:23:10 2024 GMT
            Not After : Apr 11 03:23:10 2034 GMT
        Subject: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = thirdca, emailAddress = thirdca@test.com
        Subject Public Key Info:
            Public Key Algorithm: sm2
                Public-Key: (256 bit)
                pub:
                    04:ab:fc:54:30:8f:8f:37:28:34:6b:7a:a8:6a:12:
                    65:84:08:e3:6b:bc:ef:3a:ed:85:c1:b9:7d:29:14:
                    6f:11:7f:b0:ba:76:2c:89:20:8e:d1:31:7d:80:c4:
                    68:b8:88:24:ac:92:e5:78:72:12:bc:d1:01:66:29:
                    13:f9:2b:93:81
                Field Type: prime-field
                Prime:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:ff
                A:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:fc
                B:
                    28:e9:fa:9e:9d:9f:5e:34:4d:5a:9e:4b:cf:65:09:
                    a7:f3:97:89:f5:15:ab:8f:92:dd:bc:bd:41:4d:94:
                    0e:93
                Generator (uncompressed):
                    04:32:c4:ae:2c:1f:19:81:19:5f:99:04:46:6a:39:
                    c9:94:8f:e3:0b:bf:f2:66:0b:e1:71:5a:45:89:33:
                    4c:74:c7:bc:37:36:a2:f4:f6:77:9c:59:bd:ce:e3:
                    6b:69:21:53:d0:a9:87:7c:c6:2a:47:40:02:df:32:
                    e5:21:39:f0:a0
                Order:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:72:03:df:6b:21:c6:05:2b:53:bb:f4:09:39:
                    d5:41:23
                Cofactor:  1 (0x1)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                C1:0D:90:4B:C2:CF:9A:64:48:D7:C5:92:F6:B9:AB:73:95:A1:74:9A
            X509v3 Authority Key Identifier:
                00:5F:38:E1:B9:68:22:D4:01:6B:FC:68:A3:56:58:7A:19:88:66:3C
            X509v3 Basic Constraints: critical
                CA:TRUE  # 这里表明该证书可用于签名其他证书
    Signature Algorithm: SM2-with-SM3
    Signature Value:
        30:45:02:21:00:c2:09:8e:2f:65:2c:4f:75:52:75:33:7b:0c:
        a6:91:f7:74:8e:28:b5:c7:0b:f9:7c:6d:6f:48:e3:f5:4e:9a:
        c3:02:20:51:67:dc:fe:30:4c:db:fc:aa:46:7c:06:6c:b3:ed:
        bd:33:52:a0:e3:ca:bf:e4:22:b7:86:df:da:f5:86:fa:69

服务端证书

Server证书生成脚本get_servercert.sh内容如下:

#!/bin/bash

# 创建相关目录
if ! mkdir -p "$HOME"/Server ;
then
    echo "mkdir failed"
    exit 1
fi

# # cd失败立即退出
cd "$HOME/Server" || { echo "cd $HOME/Server failed and remove $HOME/Server and exit 1"; rm -rf "$HOME"/Server ; exit 1; }

# ~/Server 中执行以下命令
#
# 定义相关变量
#
C=CN            # 国家
ST=SH           # 省份
L=XA            # 城市
O=demo          # 组织
OU=demo         # 部门
CN=servercert   # 通用名
email=servercert@test.com               # 邮箱
ServerKey=serverkey.pem                 # 生成的Server私钥
ServerCert=servercert.pem               # pem格式的Server证书
ServerCertCRT=servercert.crt            # crt格式的Server证书
ServerCSR=servercert.csr                # 生成证书时的签名请求文件
SignCert="$HOME"/ThirdCA/thirdca.crt    # 签名证书
SignKey="$HOME"/ThirdCA/thirdkey.pem    # 签名私钥
ChainCert=ca-chain.crt                  # 证书链
# 生成Server证书SM2私钥
if ! openssl ecparam -genkey -name SM2 -param_enc explicit -outform pem -out "$ServerKey";
then
    echo "generate SM2 server private key failed and remove $HOME/Server and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Server ;
    exit 1;
fi
#
# 使用SM2私钥创建签名请求
if ! openssl req -new -key "$ServerKey" -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN/emailAddress=$email" -config "$HOME"/openssl.cnf -out "$ServerCSR";
then
    echo "generate SM2 servert csr failed failed and remove $HOME/Server and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Server ;
    exit 1;
fi

# 使用三级CA进行签名,这里要指定签名的证书与私钥
if [ ! -f "$SignKey" ] || [ ! -f "$SignCert" ];
then
    echo "$SignKey or $SignCert doesn't exist and remove $HOME/Server and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Server ;
    exit 1;
fi
# -extensions v3_ca 这里要去掉该参数,这个参数用于指定当前在证书是否可以认证其他证书
if ! openssl ca -in "$ServerCSR" -cert "$SignCert" -keyfile "$SignKey" -days 3650 -config "$HOME"/openssl.cnf -out "$ServerCert";
then
    echo "generate SM2 thirdca certificate failed failed and remove $HOME/Server and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Server ;
    exit 1;
fi

# pem格式证书转为crt
if ! openssl x509 -in "$ServerCert" -out "$ServerCertCRT";
then
    echo "pem convert to crt failed and remove $HOME/Server and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Server ;
    exit 1;
fi

# 将根证书与二级证书合并为证书链

echo "-----------------------------------------------------------------"
echo "~$ cat $SignCert $HOME/SecondCA/secondca.crt $HOME/CA/rootca.crt > $ChainCert"
if ! cat "$SignCert" "$HOME"/SecondCA/secondca.crt "$HOME"/CA/rootca.crt > "$ChainCert";
then
    echo "generate cert chain file failed and remove $HOME/Server and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Server ;
    exit 1;
fi

echo "-----------------------------------------------------------------"
echo "~$ tree"
tree

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $ChainCert $ServerCert"
openssl verify -verbose -CAfile "$ChainCert" "$ServerCert"

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $ChainCert $ServerCertCRT"
openssl verify -verbose -CAfile "$ChainCert" "$ServerCertCRT"

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -in $ServerCertCRT -noout -dates"
openssl x509 -in "$ServerCertCRT" -noout -dates

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -noout -text -in $ServerCertCRT"
openssl x509 -noout -text -in "$ServerCertCRT"

Server证书生成结果如下:

~$ ./gen_servercert.sh
Using configuration from /home/xxx/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 4 (0x4)
        Validity
            Not Before: Apr 13 03:25:29 2024 GMT
            Not After : Apr 11 03:25:29 2034 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = SH
            localityName              = XA
            organizationName          = demo
            organizationalUnitName    = demo
            commonName                = servercert
            emailAddress              = servercert@test.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Subject Key Identifier:
                50:EB:78:B5:06:71:C4:BC:B9:B5:AC:C4:ED:A5:05:21:96:35:EA:8B
            X509v3 Authority Key Identifier:
                C1:0D:90:4B:C2:CF:9A:64:48:D7:C5:92:F6:B9:AB:73:95:A1:74:9A
Certificate is to be certified until Apr 11 03:25:29 2034 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Database updated
-----------------------------------------------------------------
~$ cat /home/xxx/ThirdCA/thirdca.crt /home/xxx/SecondCA/secondca.crt /home/xxx/CA/rootca.crt > ca-chain.crt
-----------------------------------------------------------------
~$ tree
.
├── ca-chain.crt
├── servercert.crt
├── servercert.csr
├── servercert.pem
└── serverkey.pem

1 directory, 5 files
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile ca-chain.crt servercert.pem
servercert.pem: OK
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile ca-chain.crt servercert.crt
servercert.crt: OK
-----------------------------------------------------------------
~$ openssl x509 -in servercert.crt -noout -dates
notBefore=Apr 13 03:25:29 2024 GMT
notAfter=Apr 11 03:25:29 2034 GMT
-----------------------------------------------------------------
~$ openssl x509 -noout -text -in servercert.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4 (0x4)
        Signature Algorithm: SM2-with-SM3
        Issuer: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = thirdca, emailAddress = thirdca@test.com
        Validity
            Not Before: Apr 13 03:25:29 2024 GMT
            Not After : Apr 11 03:25:29 2034 GMT
        Subject: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = servercert, emailAddress = servercert@test.com
        Subject Public Key Info:
            Public Key Algorithm: sm2
                Public-Key: (256 bit)
                pub:
                    04:2a:8c:9d:87:fb:34:94:89:22:48:2d:fe:8e:34:
                    a5:73:49:32:89:ca:fe:10:f8:26:4a:55:8d:92:f3:
                    05:ca:47:a0:7f:36:1c:be:5f:bc:60:9d:eb:26:8d:
                    24:fe:ff:5b:d2:e2:a5:90:ee:55:8e:fa:a1:75:1d:
                    05:ef:c9:9b:d5
                Field Type: prime-field
                Prime:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:ff
                A:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:fc
                B:
                    28:e9:fa:9e:9d:9f:5e:34:4d:5a:9e:4b:cf:65:09:
                    a7:f3:97:89:f5:15:ab:8f:92:dd:bc:bd:41:4d:94:
                    0e:93
                Generator (uncompressed):
                    04:32:c4:ae:2c:1f:19:81:19:5f:99:04:46:6a:39:
                    c9:94:8f:e3:0b:bf:f2:66:0b:e1:71:5a:45:89:33:
                    4c:74:c7:bc:37:36:a2:f4:f6:77:9c:59:bd:ce:e3:
                    6b:69:21:53:d0:a9:87:7c:c6:2a:47:40:02:df:32:
                    e5:21:39:f0:a0
                Order:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:72:03:df:6b:21:c6:05:2b:53:bb:f4:09:39:
                    d5:41:23
                Cofactor:  1 (0x1)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE  # 这里表明该证书不能签发其他证书,只有由证书链认证
            X509v3 Subject Key Identifier:
                50:EB:78:B5:06:71:C4:BC:B9:B5:AC:C4:ED:A5:05:21:96:35:EA:8B
            X509v3 Authority Key Identifier:
                C1:0D:90:4B:C2:CF:9A:64:48:D7:C5:92:F6:B9:AB:73:95:A1:74:9A
    Signature Algorithm: SM2-with-SM3
    Signature Value:
        30:45:02:21:00:ae:ed:e7:56:c0:ce:61:9f:c5:1f:f3:d5:61:
        82:ca:ee:03:1a:61:8e:a2:7a:59:e4:4f:23:7e:35:01:a9:f8:
        c9:02:20:62:aa:04:fa:f8:89:b8:58:b9:6b:a4:7c:11:37:ea:
        bf:e3:d1:bb:b0:02:69:61:cb:e5:63:39:ed:4d:28:2c:ce

客户端证书

Client证书生成脚本gen_clientcert.sh的内容如下:

#!/bin/bash

# 创建相关目录
if ! mkdir -p "$HOME"/Client ;
then
    echo "mkdir failed"
    exit 1
fi

# # cd失败立即退出
cd "$HOME/Client" || { echo "cd $HOME/Client failed and remove $HOME/Client and exit 1"; rm -rf "$HOME"/Client ; exit 1; }

# ~/Client 中执行以下命令
#
# 定义相关变量
#
C=CN            # 国家
ST=SH           # 省份
L=XA            # 城市
O=demo          # 组织
OU=demo         # 部门
CN=servercert   # 通用名
email=servercert@test.com               # 邮箱
ClientKey=clientkey.pem                 # 生成的Client私钥
ClientCert=clientcert.pem               # pem格式的Client证书
ClientCertCRT=clientcert.crt            # crt格式的Client证书
ClientCSR=clientcert.csr                # 生成证书时的签名请求文件
SignCert="$HOME"/ThirdCA/thirdca.crt    # 签名证书
SignKey="$HOME"/ThirdCA/thirdkey.pem    # 签名私钥
ChainCert=ca-chain.crt                  # 证书链

# 生成Client证书SM2私钥
if ! openssl ecparam -genkey -name SM2 -param_enc explicit -outform pem -out "$ClientKey";
then
    echo "generate SM2 client private key failed and remove $HOME/Client and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Client ;
    exit 1;
fi
#
# 使用SM2私钥创建签名请求
if ! openssl req -new -key "$ClientKey" -subj "/C=$C/ST=$ST/L=$L/O=$O/OU=$OU/CN=$CN/emailAddress=$email" -config "$HOME"/openssl.cnf -out "$ClientCSR";
then
    echo "generate SM2 client csr failed failed and remove $HOME/Client and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Client ;
    exit 1;
fi

# 使用三级CA进行签名,这里要指定签名的证书与私钥
if [ ! -f "$SignKey" ] || [ ! -f "$SignCert" ];
then
    echo "$SignKey or $SignCert doesn't exist and remove $HOME/Client and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Client ;
    exit 1;
fi
# -extensions v3_ca 这里要去掉该参数,这个参数用于指定当前在证书是否可以认证其他证书
if ! openssl ca -in "$ClientCSR" -cert "$SignCert" -keyfile "$SignKey" -days 3650 -config "$HOME"/openssl.cnf -out "$ClientCert";
then
    echo "generate SM2 client certificate failed failed and remove $HOME/Client and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Client ;
    exit 1;
fi

# pem格式证书转为crt
if ! openssl x509 -in "$ClientCert" -out "$ClientCertCRT";
then
    echo "pem convert to crt failed and remove $HOME/Client and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Client ;
    exit 1;
fi

# 将根证书与二级证书合并为证书链

echo "-----------------------------------------------------------------"
echo "~$ cat $SignCert $HOME/SecondCA/secondca.crt $HOME/CA/rootca.crt > $ChainCert"
if ! cat "$SignCert" "$HOME"/SecondCA/secondca.crt "$HOME"/CA/rootca.crt > "$ChainCert";
then
    echo "generate cert chain file failed and remove $HOME/Client and exit 1";
    cd .. || { echo "cd .. failed and exit."; exit; }
    rm -rf "$HOME"/Client ;
    exit 1;
fi

echo "-----------------------------------------------------------------"
echo "~$ tree"
tree

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $ChainCert $ClientCert"
openssl verify -verbose -CAfile "$ChainCert" "$ClientCert"

echo "-----------------------------------------------------------------"
echo "~$ openssl verify -verbose -CAfile $ChainCert $ClientCertCRT"
openssl verify -verbose -CAfile "$ChainCert" "$ClientCertCRT"

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -in $ClientCertCRT -noout -dates"
openssl x509 -in "$ClientCertCRT" -noout -dates

echo "-----------------------------------------------------------------"
echo "~$ openssl x509 -noout -text -in $ClientCertCRT"
openssl x509 -noout -text -in "$ClientCertCRT"

Client证书生成结果如下:

~$ ./gen_clientcert.sh
Using configuration from /home/xxx/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 5 (0x5)
        Validity
            Not Before: Apr 13 03:26:27 2024 GMT
            Not After : Apr 11 03:26:27 2034 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = SH
            localityName              = XA
            organizationName          = demo
            organizationalUnitName    = demo
            commonName                = clientcert
            emailAddress              = clientcert@test.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            X509v3 Subject Key Identifier:
                F9:94:D1:9C:4C:F4:6A:55:F2:68:FB:33:A9:A4:F3:F6:4E:84:5A:D9
            X509v3 Authority Key Identifier:
                C1:0D:90:4B:C2:CF:9A:64:48:D7:C5:92:F6:B9:AB:73:95:A1:74:9A
Certificate is to be certified until Apr 11 03:26:27 2034 GMT (3650 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Database updated
-----------------------------------------------------------------
~$ cat /home/xxx/ThirdCA/thirdca.crt /home/xxx/SecondCA/secondca.crt /home/xxx/CA/rootca.crt > ca-chain.crt
-----------------------------------------------------------------
~$ tree
.
├── ca-chain.crt
├── clientcert.crt
├── clientcert.csr
├── clientcert.pem
└── clientkey.pem

1 directory, 5 files
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile ca-chain.crt clientcert.pem
clientcert.pem: OK
-----------------------------------------------------------------
~$ openssl verify -verbose -CAfile ca-chain.crt clientcert.crt
clientcert.crt: OK
-----------------------------------------------------------------
~$ openssl x509 -in clientcert.crt -noout -dates
notBefore=Apr 13 03:26:27 2024 GMT
notAfter=Apr 11 03:26:27 2034 GMT
-----------------------------------------------------------------
~$ openssl x509 -noout -text -in clientcert.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 5 (0x5)
        Signature Algorithm: SM2-with-SM3
        Issuer: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = thirdca, emailAddress = thirdca@test.com
        Validity
            Not Before: Apr 13 03:26:27 2024 GMT
            Not After : Apr 11 03:26:27 2034 GMT
        Subject: C = CN, ST = SH, L = XA, O = demo, OU = demo, CN = clientcert, emailAddress = clientcert@test.com
        Subject Public Key Info:
            Public Key Algorithm: sm2
                Public-Key: (256 bit)
                pub:
                    04:1b:2b:12:2c:cb:69:d5:9a:f2:cb:f6:a3:85:35:
                    49:87:7c:c0:62:86:68:f6:7a:d5:b6:d2:83:43:3b:
                    76:dd:2b:4d:cd:26:d7:ed:58:60:65:a5:3d:fe:46:
                    15:80:ac:8e:34:ed:36:9e:1e:af:c7:39:88:15:4e:
                    ca:18:ea:2c:3e
                Field Type: prime-field
                Prime:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:ff
                A:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:
                    ff:ff:fc
                B:
                    28:e9:fa:9e:9d:9f:5e:34:4d:5a:9e:4b:cf:65:09:
                    a7:f3:97:89:f5:15:ab:8f:92:dd:bc:bd:41:4d:94:
                    0e:93
                Generator (uncompressed):
                    04:32:c4:ae:2c:1f:19:81:19:5f:99:04:46:6a:39:
                    c9:94:8f:e3:0b:bf:f2:66:0b:e1:71:5a:45:89:33:
                    4c:74:c7:bc:37:36:a2:f4:f6:77:9c:59:bd:ce:e3:
                    6b:69:21:53:d0:a9:87:7c:c6:2a:47:40:02:df:32:
                    e5:21:39:f0:a0
                Order:
                    00:ff:ff:ff:fe:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:
                    ff:ff:72:03:df:6b:21:c6:05:2b:53:bb:f4:09:39:
                    d5:41:23
                Cofactor:  1 (0x1)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE  # 这里表明该证书不能签发其他证书,只有由证书链认证
            X509v3 Subject Key Identifier:
                F9:94:D1:9C:4C:F4:6A:55:F2:68:FB:33:A9:A4:F3:F6:4E:84:5A:D9
            X509v3 Authority Key Identifier:
                C1:0D:90:4B:C2:CF:9A:64:48:D7:C5:92:F6:B9:AB:73:95:A1:74:9A
    Signature Algorithm: SM2-with-SM3
    Signature Value:
        30:44:02:20:27:93:e7:01:54:d2:1c:fa:34:e9:a3:1f:60:41:
        8f:7d:c7:c1:79:47:6a:92:95:6b:10:96:47:33:fd:8b:9c:3d:
        02:20:37:34:d7:8a:29:2a:71:8e:7c:5a:08:3a:8f:94:24:83:
        49:37:26:1b:b1:d4:62:ae:7c:11:f1:a4:e1:5b:55:b4