GmSSL制作国密算法自签证书和 HTTPS 配置

GmSSL 是一个开源(遵循 BSD 协议)的密码工具箱,支持 SM2 / SM3 / SM4 / SM9 / ZUC 等国密(国家商用密码)算法、SM2 国密数字证书及基于 SM2 证书的 SSL / TLS 安全通信协议,支持国密硬件密码设备,提供符合国密规范的编程接口与命令行工具,可以用于构建 PKI / CA 、安全通信、数据加密等符合国密标准的安全应用。GmSSL 项目是 OpenSSL 项目的分支,并与 OpenSSL 保持接口兼容。因此 GmSSL 可以替代应用中的 OpenSSL 组件,并使应用自动具备基于国密的安全能力。

目前已发布的 GmSSL 仅适配 RedHat/CentOS7,更高的 RedHat/CentOS 系统在运行 GmSSL 时可能出现链接库文件无法适配的问题。

国产密码算法(国密算法)是指国家密码局认定的国产商用密码算法,国密算法系列包括 SM1,SM2,SM3,SM4,SM7,SM9 和 ZUC 算法,与国际通用算法标准有对应关系。其中对称密码算法包括 SM1,SM4 和 SM7,非对称密码算法包括 SM2,SM9,哈希算法包括 SM3。

  • SM1 算法:仅支持硬件实现,目前使用范围逐渐萎缩,目前主要在存量市场有所使用。
  • SM2 算法:对标 RSA、ECC 算法,算法标准已公开。
  • SM3 算法:对标 MD5、SHA-256 等哈希算法,算法标准已公开。
  • SM4 算法:对标 AES,3DES 等算法,算法标准已公开。
  • SM7 算法:针对非接触式 IC 卡、票务、支付卡类应用,算法标准已公开。
  • SM9 算法:ZUC 算法属于对称密码算法中的序列密码算法,以 32 位字为单位输出密钥流,其密钥长度和 IV 长度均为 128 比特。

目录

1.GmSSL 制作自签证书
1.1.第一阶段:制作 CA 根证书
1.2.第二阶段:制作服务器证书
1.3.第三阶段:制作客户端证书(双向认证使用)

2.Web 容器配置 HTTPS站点
2.1.Tomcat 配置方案
2.2.Nginx 配置方案
2.3.Apache Httpd 配置方案

3.客户端访问
3.1.安装 CA 机构证书
3.2.安装客户端 PKCS12 证书(双向认证使用)
3.3.常见问题

后记一:HTTPS 和 SSL 的概念和工作原理

1.GmSSL 制作自签证书

1、安装 GmSSL。

1)验证并安装依赖软件。通过源代码编译的方式安装 GmSSL,需要依赖软件"make"、"gcc",验证或安装依赖软件:

$ sudo yum install make gcc

补充知识:

① "gcc"是一个C/C++、FORTRAN、JAVA、OBJC、ADA等多种语言的编译器,用来将源代码编译成可发布的软件程序。

② "make"是一个工程管理工具,能够根据 Makefile 中的脚本执行编译、安装流程。

2)打开 GmSSL 下载页面【https://github.com/guanzhi/GmSSL】,下载 GmSSL 源代码 zip 包到用户主目录中:

3)解压缩 GmSSL 的源代码 zip 包到用户主目录下:

$ unzip GmSSL-master.zip
$ ll
drwxrwxr-x. 24 centos centos    4096 8月  24 21:46 GmSSL-master

4)安装 GmSSL,进入源代码目录,配置、编译、安装程序,并拷贝链接库文件("libcrypto.so.1.1"、"libssl.so.1.1")到系统链接库目录("/lib64")中:

$ cd GmSSL-master
$ ./config
$ make
$ sudo make install
$ sudo cp libcrypto.so.1.1 libssl.so.1.1 /lib64

程序安装目录是"/usr/local/bin"。

5)查看 GmSSL 的链接库文件是否正常:

$ ldd /usr/local/bin/gmssl

linux-vdso.so.1 =>  (0x00007fffc0cc2000)
libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007f9fd0a46000)
libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007f9fd04f2000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f9fd02ee000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f9fd00d2000)
libc.so.6 => /lib64/libc.so.6 (0x00007f9fcfd04000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9fd0cbd000)

2、创建 SSL 工作目录。

证书包括 CA 认证机构、服务器和客户端三类证书的制作,在 SSL 工作根目录下分别建立"ca"、"server"、"client"子目录存放对应的输出文件,并设置所有者为证书管理账户。

$ sudo mkdir -p /data/ssl/ca
$ sudo mkdir -p /data/ssl/server
$ sudo mkdir -p /data/ssl/client
$ sudo chown -R centos:centos /data/ssl

3、术语说明

文件类型                                  说明
KEY                  非对称私钥文件,文件扩展名通常为 ".key"
CSR                 只包含公钥的证书签名申请,文件扩展名通常为 ".csr"
PEM                 只包含公钥的证书,文件扩展名通常为 ".pem"
PKCS12           包含公钥和私钥证书,文件扩展名通常为 ".p12"

1.1.第一阶段:制作 CA 根证书

1、制作 CA【秘钥】。

$ gmssl ecparam -genkey -name sm2p256v1 -out /data/ssl/ca/ca.key

说明:

  • 【openssl ecparam】表示制作秘钥。
  • 【-genkey】表示生成一个 EC 秘钥;
  • 【-name】表示 EC 密码的算法。
  • 【-out】表示秘钥的输出文件。

查看 CA 秘钥文件:

gmssl ec -in /data/ssl/ca/ca.key

2、制作 CA 【根证书签名申请】。

输入 CA 秘钥文件,输出 CA 根证书签名申请文件。

操作过程:验证 CA 秘钥口令 => 设置国家名称 => 设置省份名称 => 设置城市名称 => 设置组织机构名称 => 设置组织单元名称 => 设置证书名称 => 设置电子邮件地址和扩展属性(密码提示信息和可选的公司名称)。

$ gmssl req -new -key /data/ssl/ca/ca.key -out /data/ssl/ca/ca.csr

Enter pass phrase for /data/ssl/ca/ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:ch
State or Province Name (full name) []:sd
Locality Name (eg, city) [Default City]:qd 
Organization Name (eg, company) [Default Company Ltd]:private
Organizational Unit Name (eg, section) []:zhangyi
Common Name (eg, your name or your server's hostname) []:ca
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

说明:

  • 【openssl req】表示制作证书签名申请。
  • 【-new】表示生成证书请求文件;
  • 【-key】表示秘钥的输入文件;
  • 【-out】表示证书签名申请的输出文件。

注意:【Common Name】应为 CA 机构的名称。

查看 CA 证书申请文件:

$ gmssl req -in /data/ssl/ca/ca.csr -noout -text

3、生成 CA 自签【根证书】,即对签名申请进行自签生成证书。

输入 CA 秘钥文件、CA 根证书签名申请,输出 CA 自签根证书文件。

$ gmssl x509 -req -days 3650 -sm3 -signkey /data/ssl/ca/ca.key -in /data/ssl/ca/ca.csr -out /data/ssl/ca/ca.pem

Signature ok
subject=C = ch, ST = sd, L = qd, O = private, OU = zhangyi, CN = ca
Getting Private key

说明:

  • 【openssl x509】表示制作自签证书。
  • 【-req】表示输入文件的类型是证书签名申请;
  • 【-days】表示证书的有效期,单位是天;
  • 【-sm3】表示使用 SM3 加密算法进行签名;
  • 【-signkey】表示签名秘钥的输入文件;
  • 【-in】表示证书签名申请的输入文件;
  • 【-out】表示证书的输出文件。

查看 CA 证书文件:

$ gmssl x509 -in /data/ssl/ca/ca.pem -noout -text

4、导出 CA【 PKCS12 证书】。

输入 CA 自签的 CA 证书文件、CA 秘钥,输出 CA PKCS12 证书。

操作过程:设置 PKCS12 证书口令。

$ gmssl pkcs12 -export -in /data/ssl/ca/ca.pem -inkey /data/ssl/ca/ca.key -out /data/ssl/ca/ca.p12 -name ca

Enter Export Password:
Verifying - Enter Export Password:

说明:

  • 【openssl pkcs12】表示制作 PKCS12 证书。
  • 【-export 】表示导出 PKCS12 证书;
  • 【-in】表示签名证书的输入文件;
  • 【-inkey】表示秘钥的输入文件;
  • 【-name】表示 PKCS12 证书的别名;
  • 【-out】表示 PKCS12 证书的输出文件。

查看 CA PKCS12 证书文件(需要输入 CA PKCS12 证书口令):

$ gmssl pkcs12 -in /data/ssl/ca/ca.p12 -info
Enter Import Password:
......

Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
......

5、查看 CA 产生的全部文件。

$ ls /data/ssl/ca/
ca.csr  ca.key  ca.p12  ca.pem

1.2.第二阶段:制作服务器证书

1、制作服务器【秘钥】。

$ gmssl ecparam -genkey -name sm2p256v1 -out /data/ssl/server/server.key

说明:

  • 【openssl ecparam】表示制作秘钥。
  • 【-genkey】表示生成一个 EC 秘钥;
  • 【-name】表示 EC 密码的算法。
  • 【-out】表示秘钥的输出文件。

查看服务器秘钥文件:

gmssl ec -in /data/ssl/server/server.key

2、制作服务器【证书签名申请】。

输入服务器秘钥文件,输出服务器证书签名申请文件。

操作过程:验证服务器秘钥口令 => 设置国家名称 => 设置省份名称 => 设置城市名称 => 设置组织机构名称 => 设置组织单元名称 => 设置证书名称 => 设置电子邮件地址和扩展属性(密码提示信息和可选的公司名称)。

$ gmssl req -new -key /data/ssl/server/server.key -out /data/ssl/server/server.csr

Enter pass phrase for /data/ssl/server/server.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:ch
State or Province Name (full name) []:sd
Locality Name (eg, city) [Default City]:qd
Organization Name (eg, company) [Default Company Ltd]:private
Organizational Unit Name (eg, section) []:zhangyi
Common Name (eg, your name or your server's hostname) []:192.168.216.128
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

说明:

  • 【openssl req】表示制作证书签名申请。
  • 【-new】表示生成证书请求文件;
  • 【-key】表示秘钥的输入文件;
  • 【-out】表示证书签名申请的输出文件。

注意:【Common Name】应为服务器的 IP 地址或者 DNS(如:192.168.216.128 或者 localhost)。在 在 Web 容器配置后,当客户端使用 HTTPS 协议访问时,如果域名与【Common Name】不一致,则会进行风险提示。

查看服务器证书申请文件:

$ gmssl req -in /data/ssl/server/server.csr -noout -text

3、生成 CA 签名的服务器【证书】,即 CA 对服务器签名申请进行签名生成服务器证书。

输入 CA 根证书文件、 CA 秘钥文件、服务器证书签名申请,输出 CA 签名的服务器证书文件。

$ gmssl x509 -req -days 3650 -sm3 -CA /data/ssl/ca/ca.pem -CAkey /data/ssl/ca/ca.key -CAcreateserial -in /data/ssl/server/server.csr -out /data/ssl/server/server.pem

Signature ok
subject=C = ch, ST = sd, L = qd, O = private, OU = zhangyi, CN = 192.168.216.128
Getting CA Private Key

说明:

  • 【openssl x509】表示制作 CA 签名的证书。
  • 【-req】表示输入文件的类型是证书签名申请;
  • 【-days】表示证书的有效期,单位是天;
  • 【-sm3】表示使用 SM3 加密算法进行签名;
  • 【-CA】表示 CA 根证书的输入文件;
  • 【-CAkey】表示 CA 秘钥的输入文件;
  • 【-CAcreateserial】表示如果 CA 序列号文件不存在自动创建;
  • 【-in】表示证书签名申请的输入文件;
  • 【-out】表示证书的输出文件。

查看服务器证书文件:

$ gmssl x509 -in /data/ssl/server/server.pem -noout -text

使用 CA 证书验证服务器证书文件:

$ gmssl verify -CAfile /data/ssl/ca/ca.pem /data/ssl/server/server.pem
/data/ssl/server/server.pem: OK

4、导出服务器【 PKCS12 证书】。

输入 CA 签名的服务器证书文件、服务器秘钥,输出服务器 PKCS12 证书。

操作过程:设置 PKCS12 证书口令。

$ gmssl pkcs12 -export -in /data/ssl/server/server.pem -inkey /data/ssl/server/server.key -out /data/ssl/server/server.p12 -name https_cert

Enter Export Password:
Verifying - Enter Export Password:

说明:

  • 【openssl pkcs12】表示制作 PKCS12 证书。
  • 【-export 】表示导出 PKCS12 证书;
  • 【-in】表示签名证书的输入文件;
  • 【-inkey】表示秘钥的输入文件;
  • 【-name】表示 PKCS12 证书的别名;
  • 【-out】表示 PKCS12 证书的输出文件。

查看服务器 PKCS12 证书文件(需要输入服务器 PKCS12 证书口令):

$ gmssl pkcs12 -in /data/ssl/server/server.p12 -info
Enter Import Password:
......

Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
......

5、查看服务器产生的全部文件。

$ ls /data/ssl/server
server.csr  server.key  server.p12  server.pem

1.3.第三阶段:制作客户端证书(双向认证时使用)

1、制作客户端【秘钥】。

$ gmssl ecparam -genkey -name sm2p256v1 -out /data/ssl/client/client.key

说明:

  • 【openssl ecparam】表示制作秘钥。
  • 【-genkey】表示生成一个 EC 秘钥;
  • 【-name】表示 EC 密码的算法。
  • 【-out】表示秘钥的输出文件。

查看客户端秘钥文件:

 gmssl ec -in /data/ssl/client/client.key

2、制作客户端【证书签名申请】。

输入客户端秘钥文件,输出客户端证书签名申请文件。

操作过程:验证客户端秘钥口令 => 设置国家名称 => 设置省份名称 => 设置城市名称 => 设置组织机构名称 => 设置组织单元名称 => 设置证书名称 => 设置电子邮件地址和扩展属性(密码提示信息和可选的公司名称)。

$ gmssl req -new -key /data/ssl/client/client.key -out /data/ssl/client/client.csr

nter pass phrase for /data/ssl/client/client.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:ch
State or Province Name (full name) []:sd
Locality Name (eg, city) [Default City]:qd
Organization Name (eg, company) [Default Company Ltd]:private
Organizational Unit Name (eg, section) []:zhangyi
Common Name (eg, your name or your server's hostname) []:https_client
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

说明:

  • 【openssl req】表示制作证书签名申请。
  • 【-new】表示生成证书请求文件;
  • 【-key】表示秘钥的输入文件;
  • 【-out】表示证书签名申请的输出文件。

注意:【Common Name】应为客户端的统一标识。

查看客户端证书申请文件:

$ gmssl req -in /data/ssl/client/client.csr -noout -text

3、生成 CA 签名的客户端【证书】,即 CA 对客户端签名申请进行签名生成客户端证书。

输入 CA 根证书文件、 CA 秘钥文件、客户端证书签名申请,输出 CA 签名的客户端证书文件。

$ gmssl x509 -req -days 3650 -sm3 -CA /data/ssl/ca/ca.pem -CAkey /data/ssl/ca/ca.key -CAcreateserial -in /data/ssl/client/client.csr -out /data/ssl/client/client.pem

Signature ok
subject=C = ch, ST = sd, L = qd, O = private, OU = zhangyi, CN = https_client
Getting CA Private Key

说明:

  • 【openssl x509】表示制作 CA 签名的证书。
  • 【-req】表示输入文件的类型是证书签名申请;
  • 【-days】表示证书的有效期,单位是天;
  • 【-sm3】表示使用 SM3 加密算法进行签名;
  • 【-CA】表示 CA 根证书的输入文件;
  • 【-CAkey】表示 CA 秘钥的输入文件;
  • 【-CAcreateserial】表示如果 CA 序列号文件不存在自动创建;
  • 【-in】表示证书签名申请的输入文件;
  • 【-out】表示证书的输出文件。

查看客户端证书文件:

$ gmssl x509 -in /data/ssl/client/client.pem -noout -text

使用 CA 证书验证服务器证书文件:

$ gmssl verify -CAfile /data/ssl/ca/ca.pem /data/ssl/client/client.pem
/data/ssl/client/client.pem: OK

4、导出客户端【 PKCS12 证书】。

输入 CA 签名的客户端证书文件、客户端秘钥,输出客户端 PKCS12 证书。

操作过程:设置 PKCS12 证书口令。

$ gmssl pkcs12 -export -in /data/ssl/client/client.pem -inkey /data/ssl/client/client.key -out /data/ssl/client/client.p12 -name https_client

Enter Export Password:
Verifying - Enter Export Password:

说明:

  • 【openssl pkcs12】表示制作 PKCS12 证书。
  • 【-export 】表示导出 PKCS12 证书;
  • 【-in】表示签名证书的输入文件;
  • 【-inkey】表示秘钥的输入文件;
  • 【-name】表示 PKCS12 证书的别名;
  • 【-out】表示 PKCS12 证书的输出文件。

查看客户端 PKCS12 证书文件(需要输入服务器 PKCS12 证书口令):

$ gmssl pkcs12 -in /data/ssl/client/client.p12 -info
Enter Import Password:
......

Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
......

5、查看客户端产生的全部文件。

$ ls /data/ssl/client
client.csr  client.key  client.p12  client.pem

2.Web 容器配置 HTTPS 站点

2.1.Tomcat 配置方案

1、安装并配置 Tomcat 。

 sudo tar zxvf apache-tomcat-9.0.34.tar.gz -C /usr/local
 sudo mv /usr/local/apache-tomcat-9.0.34 /usr/local/tomcat-9.0.34
 sudo gedit /usr/local/tomcat-9.0.34/conf/server.xml

在文件中的增加以下配置并保存(服务器认证):

<Server>
    <Service>  
        <Connector
            port="443" 
            protocol="org.apache.coyote.http11.Http11NioProtocol"
            maxThreads="150"
            SSLEnabled="true"
            keystoreFile="/data/ssl/server/server.p12"
            keystoreType="PKCS12"
            keystorePass="123456a?">
    </Connector>
    </Service>  
</Server>

在文件中的增加以下配置并保存(双向认证):

<Server>
    <Service>  
        <Connector
            port="443" 
            protocol="org.apache.coyote.http11.Http11NioProtocol"
            maxThreads="150"
            SSLEnabled="true"
            keystoreFile="/data/ssl/server/server.p12"
            keystoreType="PKCS12"
            clientAuth="true"
            truststoreFile="/data/ssl/ca/ca.p12"
            truststoreType="PKCS12"
            truststorePass="123456a?">
    </Connector>
    </Service>  
</Server>

2、启动/重新启动 Tomcat 。

$ sudo /usr/local/tomcat-9.0.34/bin/startup.sh
$ sudo /usr/local/tomcat-9.0.34/bin/shutdown.sh && /usr/local/tomcat-9.0.34/bin/startup.sh

2.2.Nginx 配置方案

1、安装并配置 Nginx 。

$ sudo dnf install make gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
$ tar -zxvf nginx-1.18.0.tar.gz
$ cd nginx-1.18.0
$ ./configure  --with-http_ssl_module
$ make
$ sudo make install
$ sudo gedit /usr/local/nginx/conf/nginx.conf

在文件中的增加以下配置并保存:

http {
    server {
        listen       80;
        listen       443 ssl;

        server_name  localhost;

        # 服务器签名证书文件
        ssl_certificate      /data/ssl/server/server.pem;
        # 服务器秘钥文件
        ssl_certificate_key  /data/ssl/server/server.key;

        # 开启客户端证书认证(双向认证)
        # ssl_verify_client on; 
        # CA 证书(双向认证)
        # ssl_client_certificate /data/ssl/ca/ca.pem;
        

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            ...
        }
    }
}

2、启动/重新启动 Nginx 服务器。

$ sudo /usr/local/nginx/sbin/nginx
$ sudo /usr/local/nginx/sbin/nginx -s reload

2.3.Apache Httpd 配置方案

1、安装并配置 Apache Httpd。

$ sudo dnf install httpd
$ sudo dnf install mod_ssl openssl
$ sudo setenforce 0
$ sudo gedit /etc/httpd/conf.d/ssl.conf

在文件中的编辑以下配置并保存:

# 监听端口
Listen 443 https
# Https 根路径
DocumentRoot "/var/www/html"
# 服务器域名
ServerName localhost
# 服务器签名证书文件
SSLCertificateFile /data/ssl/server/server.pem
# 服务器秘钥文件
SSLCertificateKeyFile /data/ssl/server/server.key

# 开启客户端证书认证(双向认证)
# SSLVerifyClient require  

# CA 证书(双向认证)
# SSLCACertificateFile  /data/ssl/ca/ca.pem

2、启动/重新启动 Apache Httpd 服务器。

$ sudo systemctl start httpd.service
$ sudo systemctl restart httpd.service

3.客户端配置

3.1.安装 CA 机构证书

                         第1步

                          第2步

                             第3步

                             第4步

                             第5步

                             第6步

3.2.安装客户端 PKCS12 证书(双向认证使用)

1、参照章节"3.1.安装 CA 机构证书",安装 CA 机构证书。

2、安装客户端 PKCS12 证书。

                            第1步

                         第2步

                           第3步

                           第4步

                             第5步

                            第6步

Nginx配置SSL证书部署https支持

免费ssl证书申请

申请免费的SSL证书

沃通、阿里云 申请免费的SSL证书

下载www.iamle.com.zip文件,解压文件,找到for Nginx.zip解压,得到2个文件

1_www.iamle.com_bundle.crt ,2_www.iamle.com.key

改个名字www.iamle.com.crt,www.iamle.com.key传到服务器上备用

找到对应的server,增加
listen          443 ssl;
ssl                     on;
ssl_certificate         /usr/local/nginx/conf/ssl/www.iamle.com.crt;
ssl_certificate_key     /usr/local/nginx/conf/ssl/www.iamle.com.key;
ssl_session_timeout     5m;
ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers             ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers       on;

重新载入nginx配置

# /etc/init.d/nginx  reload

转换pfx为nginx需要的crt,key

如果已经有一个扩展名为pfx的证书,那么需要转换使用

# openssl pkcs12 -in www.iamle.com.pfx -nocerts -nodes -out www.iamle.com.key
Enter Import Password: 输入证书密码
MAC verified OK

# openssl pkcs12 -in www.iamle.com.pfx -clcerts -nokeys -out www.iamle.com.crt
Enter Import Password: 输入证书密码
MAC verified OK

生成2个文件 www.iamle.com.key , www.iamle.com.pfx 复制到你指定的目录

 

https://www.jianshu.com/p/983ee30af32c    大佬文章

原文地址:https://www.cnblogs.com/zjz20/p/13624082.html