OpenSSL 完全指南

openssl

OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

在OpenSSL被曝出现严重安全漏洞后,发现多数通过SSL协议加密的网站使用名为OpenSSL的开源软件包。由于这是互联网应用最广泛的安全传输方法,被网银、在线支付、电商网站、门户网站、电子邮件等重要网站广泛使用,所以该漏洞影响范围广大。

OpenSSL有两种运行模式:交互模式和批处理模式。

直接输入openssl回车进入交互模式,输入带命令选项的openssl进入批处理模式。

OpenSSL整个软件包大概可以分成三个主要的功能部分:

  • 密码算法库
  • SSL协议库
  • 应用程序。

OpenSSL的目录结构自然也是围绕这三个功能部分进行规划的。

1.对称加密算法

OpenSSL一共提供了8种对称加密算法,其中7种是分组加密算法,仅有的一种流加密算法是RC4。这7种分组加密算法分别是AES、DES、Blowfish、CAST、IDEA、RC2、RC5,都支持电子密码本模式(ECB)、加密分组链接模式(CBC)、加密反馈模式(CFB)和输出反馈模式(OFB)四种常用的分组密码加密模式。其中,AES使用的加密反馈模式(CFB)和输出反馈模式(OFB)分组长度是128位,其它算法使用的则是64位。事实上,DES算法里面不仅仅是常用的DES算法,还支持三个密钥和两个密钥3DES算法。

2.非对称加密算法

OpenSSL一共实现了4种非对称加密算法,包括DH算法、RSA算法、DSA算法和椭圆曲线算法(EC)。DH算法一般用户密钥交换。RSA算法既可以用于密钥交换,也可以用于数字签名,当然,如果你能够忍受其缓慢的速度,那么也可以用于数据加密。DSA算法则一般只用于数字签名。

3.信息摘要算法

OpenSSL实现了5种信息摘要算法,分别是MD2、MD5、MDC2、SHA(SHA1)和RIPEMD。SHA算法事实上包括了SHA和SHA1两种信息摘要算法,此外,OpenSSL还实现了DSS标准中规定的两种信息摘要算法DSS和DSS1。

4.密钥和证书管理

密钥和证书管理是PKI的一个重要组成部分,OpenSSL为之提供了丰富的功能,支持多种标准。

首先,OpenSSL实现了ASN.1的证书和密钥相关标准,提供了对证书、公钥、私钥、证书请求以及CRL等数据对象的DER、PEM和BASE64的编解码功能。OpenSSL提供了产生各种公开密钥对和对称密钥的方法、函数和应用程序,同时提供了对公钥和私钥的DER编解码功能。并实现了私钥的PKCS#12和PKCS#8的编解码功能。OpenSSL在标准中提供了对私钥的加密保护功能,使得密钥可以安全地进行存储和分发。

在此基础上,OpenSSL实现了对证书的X.509标准编解码、PKCS#12格式的编解码以及PKCS#7的编解码功能。并提供了一种文本数据库,支持证书的管理功能,包括证书密钥产生、请求产生、证书签发、吊销和验证等功能。

事实上,OpenSSL提供的CA应用程序就是一个小型的证书管理中心(CA),实现了证书签发的整个流程和证书管理的大部分机制。

openssl 用法

介绍

查看OpenSSL是什么版本?

使用version选项

$ openssl version
OpenSSL 0.9.8zh 14 Jan 2016

跟上-a选项能得到更多的信息:

$ openssl versoin -a
OpenSSL 0.9.8zh 14 Jan 2016
built on: May 15 2016
platform: darwin64-x86_64-llvm
options:  bn(64,64) md2(int) rc4(ptr,char) des(idx,cisc,16,int) blowfish(idx)
compiler: -arch x86_64 -fmessage-length=0 -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -O3 -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DMD32_REG_T=int -DOPENSSL_NO_IDEA -DOPENSSL_PIC -DOPENSSL_THREADS -DZLIB -mmacosx-version-min=10.6
OPENSSLDIR: "/System/Library/OpenSSL"

查看有哪些命令选项?

内置的查看命令(比如openssl list-standard-commands)只能查出一组,有个技巧是加上一个无效的选项(比如help或-h),就可以得到所有的结果。

$ openssl help
openssl:Error: 'help' is an invalid command.

Standard commands
asn1parse      ca             ciphers        crl            crl2pkcs7
dgst           dh             dhparam        dsa            dsaparam
ec             ecparam        enc            engine         errstr
gendh          gendsa         genrsa         nseq           ocsp
passwd         pkcs12         pkcs7          pkcs8          prime
rand           req            rsa            rsautl         s_client
s_server       s_time         sess_id        smime          speed
spkac          verify         version        x509

Message Digest commands (see the `dgst' command for more details)
md2            md4            md5            mdc2           rmd160
sha            sha1

Cipher commands (see the `enc' command for more details)
aes-128-cbc    aes-128-ecb    aes-192-cbc    aes-192-ecb    aes-256-cbc
aes-256-ecb    base64         bf             bf-cbc         bf-cfb
bf-ecb         bf-ofb         cast           cast-cbc       cast5-cbc
cast5-cfb      cast5-ecb      cast5-ofb      des            des-cbc
des-cfb        des-ecb        des-ede        des-ede-cbc    des-ede-cfb
des-ede-ofb    des-ede3       des-ede3-cbc   des-ede3-cfb   des-ede3-ofb
des-ofb        des3           desx           rc2            rc2-40-cbc
rc2-64-cbc     rc2-cbc        rc2-cfb        rc2-ecb        rc2-ofb
rc4            rc4-40         seed           seed-cbc       seed-cfb
seed-ecb       seed-ofb

所谓“Standard commands”就是openssl后跟的第一个命令选项,可以使用同样的技巧查看有哪些可执行的子选项。

$ openssl dgst -h
unknown option '-h'
options are
-c              to output the digest with separating colons
-d              to output debug info
-hex            output as hex dump
-binary         output in binary form
-sign   file    sign digest using private key in file
-verify file    verify a signature using public key in file
-prverify file  verify a signature using private key in file
-keyform arg    key file format (PEM or ENGINE)
-signature file signature to verify
-binary         output in binary form
-hmac key       create hashed MAC with key
-engine e       use engine e, possibly a hardware device.
-md5            to use the md5 message digest algorithm (default)
-md4            to use the md4 message digest algorithm
-md2            to use the md2 message digest algorithm
-sha1           to use the sha1 message digest algorithm
-sha            to use the sha message digest algorithm
-sha224         to use the sha224 message digest algorithm
-sha256         to use the sha256 message digest algorithm
-sha384         to use the sha384 message digest algorithm
-sha512         to use the sha512 message digest algorithm
-mdc2           to use the mdc2 message digest algorithm
-ripemd160      to use the ripemd160 message digest algorithm

你也可是使用man openssl查看详细。

查看支持哪些算法?

使用ciphers选项,更多用法参见ciphers的说明文档。

# 列出所有可用的算法
openssl ciphers -v

# 列出符合TLSv1协议的算法
openssl ciphers -v -tls1

# 列出高级别加密的算法(密钥长度大于128位)
openssl ciphers -v 'HIGH'

# 列出使用了AES的高级别加密算法
openssl ciphers -v 'AES+HIGH'

性能测试

如何测试当前系统的运算性能?

OpenSSL的开发者在库里内置了测性能的套件,通过speed命令选项来使用。它测试在给定的时间内可以进行多少运算,而不是指定的运算需要多少时间。这样处理是很合理的,因此测试程序在性能好坏的系统上运行的时间不会相差太多。
只使用speed选项,测试所有算法的性能。

openssl speed

有两组结果,第一组表示指定的算法每秒可以处理多少字节的数据,第二组表示一次签名/验证花费的时间。
下面是在2.7GHZ Intel Xeon E5处理器上的测试结果:

The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024  bytes   8192 bytes
md2               2540.48k     5184.66k     6989.57k     7651.67k     7872.51k
mdc2                 0.00         0.00         0.00         0.00         0.00
md4              83248.41k   261068.18k   624212.82k   940529.32k  1128846.68k
md5              62411.57k   184768.36k   408835.75k   586930.52k   678061.98k
hmac(md5)        48713.62k   148265.56k   359626.67k   563050.68k   670255.79k
sha1             68829.72k   195087.40k   431001.51k   623344.42k   729505.79k
rmd160           38598.59k    96226.86k   183336.45k   235962.71k   257526.44k
rc4             480093.57k   678565.35k   783765.42k   818297.51k   838205.99k
des cbc          69500.17k    71184.75k    71491.50k    71641.77k    72010.15k
des ede3         26433.63k    26717.01k    26772.99k    26788.18k    26907.57k
idea cbc         95690.28k    99334.17k   100835.40k   100787.54k   100900.86k
seed cbc         76871.40k    77238.46k    77736.50k    77452.97k    77545.47k
rc2 cbc          48984.63k    49589.03k    50188.07k    50103.98k    50066.77k
rc5-32/12 cbc        0.00         0.00         0.00         0.00         0.00
blowfish cbc    122583.30k   129550.92k   130876.67k   131111.94k   131394.22k
cast cbc        109471.38k   114523.31k   115934.46k   116200.45k   116331.86k
aes-128 cbc     128352.23k   138604.76k   141173.42k   142832.25k   142682.79k
aes-192 cbc     107703.93k   114456.79k   117716.65k   118847.36k   118784.00k
aes-256 cbc      93374.87k    99521.51k   101198.51k   101382.49k   101635.41k
camellia-128 cbc    99270.57k   150412.42k   170346.33k   176311.91k   177913.86k
camellia-192 cbc    85896.60k   117356.52k   128556.97k   132759.72k   133425.83k
camellia-256 cbc    87351.27k   117695.15k   128972.03k   132130.47k   133455.87k
sha256           52372.61k   117766.12k   204825.69k   249974.10k   270914.90k
sha512           41278.19k   165820.37k   258298.69k   365981.70k   419864.58k
whirlpool        24803.02k    53047.07k    87593.90k   104570.54k   111159.98k
aes-128 ige     128441.31k   132981.88k   133269.08k   133738.15k   133966.51k
aes-192 ige     107831.37k   111507.07k   111800.66k   112156.67k   112219.48k
aes-256 ige      94382.07k    96351.17k    96750.68k    96958.46k    97446.44k
ghash           888644.92k  1452788.80k  1696788.74k  1763055.96k  1799086.49k
                sign    verify    sign/s verify/s
rsa  512 bits 0.000049s 0.000004s  20547.1 248266.2
rsa 1024 bits 0.000194s 0.000011s   5146.0  90735.4
rsa 2048 bits 0.001194s 0.000037s    837.3  27277.1
rsa 4096 bits 0.008560s 0.000137s    116.8   7324.5
                sign    verify    sign/s verify/s
dsa  512 bits 0.000048s 0.000046s  20667.7  21701.8
dsa 1024 bits 0.000113s 0.000126s   8831.9   7951.8
dsa 2048 bits 0.000362s 0.000430s   2762.0   2322.9
                            sign    verify    sign/s verify/s
256 bit ecdsa (nistp256)   0.0001s   0.0004s   9856.1   2524.4
384 bit ecdsa (nistp384)   0.0002s   0.0008s   5103.6   1191.7
521 bit ecdsa (nistp521)   0.0004s   0.0018s   2679.0    550.3
                            op      op/s
256 bit ecdh (nistp256)   0.0003s   3063.8
384 bit ecdh (nistp384)   0.0007s   1447.3
521 bit ecdh (nistp521)   0.0015s    666.2

也可以只测试指定的算法:

# 测试RSA的速度
openssl speed rsa

# 在多核系统中并行两组测试
openssl speed rsa -multi 2

如何测试远程连接的耗时?

使用s_time选项可以测试连接性能,直接调用会运行30秒,使用任意的加密算法,统计每秒钟通过SSL握手建立的连接数,结果分为新会话和重用会话两组:

openssl s_time -connect romete.host:443
# 译者注:可以拿百度来测试
openssl s_time -connect baidu.com:443

除了直接调用外,s_time选项也提供了很多测试的子选项

 只通过新会话获取远端test.html页面
openssl s_time -connect remote.host:443 -www /test.html -new

# 使用SSL v3和高级别加密算法
openssl s_time \
    -connect remote.hot:443 -www /test.html -new \
    -ssl3 -cipher HIGH

# 测试不同加密算法的性能,每种算法测试10秒
IFS=":"
for c in $(openssl ciphers -ssl3 RSA); do
    echo $C
    openssl s_time -connect remote.host:443 \
        -www / -new -time 10 -cipher $c 2>&1 | \
        grep bytes
    echo
done

如果你没有可测的启用SSL的服务端,可以使用s_server选项来创建一个。

 在一台主机上创建服务端,默认使用4433端口
openssl s_server -cert mycert.pem -www

# 在另一台主机上(可以跟服务端同一台),运行s_time
openssl s_time -connect myhost:4433 -www / -new -ssl3

证书

如何生成自签名的证书?

首先考虑是否要对私钥进行加密。
加密私钥的好处是更加安全,有人拿走了也无法使用。坏处是需要把密码保存在某个文件或每次启动服务时手动输入。
我个人倾向不加密私钥,这样不用每次手动输入。(当你厌烦输入时,要知道去除密码保护也是可以的。)
下面的例子会生成一个mycert.pem证书文件,其中证书的有效期是365天,私钥不加密(-ndoes决定的)。

openssl req \
    -x509 -nodes -days 365 -sha256 \
    -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

这个文件中有两部分信息:RSA私钥和证书。

cat mycert.pem
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

证书部分包含公钥。

openssl x509 -in mycert.pem -pubkey -noout
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

使用这个指令后,会要求你回答一系列的问题:国家,省市,公司,职位等等。当回答“Common Name”这个问题要注意点,你可能会填写主机名或域名,如果服务器的真实地址是mybox.mydomain.com,但用户是通过www.mydomain.com来访问的,那么你应填写用户访问的地址。
可以通过-subj选项来直接写入这些回答,对生成证书来说惟一有用的就是Common Name(CN)字段。

openssl req \
    -x509 -nodes -days 365 -sha256 \
    -subj '/C=US/ST=Oregon/L=Portland/CN=www.madboa.com' \
    -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

如何生成VeriSign的证书请求?

向认证机构(比如VeriSign)申请签名证书是相当繁杂和官僚的,在创建证书请求前要先准备好需要的书面文件(营业执照等)。
上一节说到,你需要考虑是否加密私钥,下面的例子假设不加密,最后会得到两个文件:私钥文件mykey.pem,证书请求文件myreq.pem。

openssl req \
    -new -sha256 -newkey rsa:2048 -nodes \
    -keyout mykey.pem -out myreq.pem

如果是使用已有的私钥文件生成证书请求,语法更简单点:

openssl req -new -key mykey.pem -out myreq.pem

同样的,你也可以在命令中直接写入要回答的问题:

openssl req \
    -new -sha256 -newkey rsa:2048 -nodes \
    -subj '/CN=www.mydom.com/O=My Dom. Inc./C=US/ST=Oregon/L=Portland' \
    -keyout mykey.pem -out myreq.pem

在跟像VeriSign这样的机构打交道时,要特别注意在创建证书请求时填写的信息。根据我个人的经验,比如填写组织名字时用and代替&,都会造成申请不通过。
需要仔细确认证书请求中的签名、组织等信息。

# 验证签名
openssl req -in myreq.pem -noout -verify -key mykey.pem
# 检查信息
openssl req -in myreq.pem -noout -text

将私钥文件保存在安全的地方,要使用VeriSign发回给你证书必须要用到它。证书请求一般是通过VeriSign的线上表单提交。

如何测试一个新证书?

s_server选项提供了一个简单有效的测试方法。下面的例子假设你已经把私钥和证书合并为一个文件(也可以是上面生成的自签名证书):mycert.pem。
首先启动测试服务端,默认使用4433端口,可以使用-accept选项修改。

openssl s_server -cert mycert.pem -www

如果服务端正常启动,没有报错信息,说明证书就可以使用了。
可以在浏览器里访问测试服务器https://yourserver:4433/。注意是https,打开这个界面可以看到可用的加密算法以及连接相关的统计。如果是自签名的证书,浏览器会提示你是否相信此证书。
怎么得到远端的证书?
只要配合使用openssl和sed命令,就能取到远端的证书信息。

#!/bin/sh
#
# usage: retrieve-cert.sh remote.host.name [port]
#
REMHOST=$1
REMPORT=${2:-443}

echo |\
openssl s_client -connect ${REMHOST}:${REMPORT} 2>&1 |\
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

也可以把得到信息再交给openssl处理,比如检查证书的日期:

#!/bin/sh
#
for CERT in \
    www.yourdomain.com:443 \
    ldap.yourdomain.com:636 \
    imap.yourdomain.com:993
do
    echo |\
    openssl s_client -connect ${CERT} 2>/dev/null |\
    sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' |\
    openssl x509 -noout -subject -dates
done

怎么查看证书中的信息?
一个SSL证书包含很多信息:颁发者,有效期,持有者,算法,公钥等。使用x509选项可以查看这些信息,下面的例子假设有一个名为cert.pem的证书文件。
使用-text选项能同时以可读文本的形式展示信息。

openssl x509 -text -in cert.pem

还有一些选项可以指定展示某项信息。

# 查看颁发者
openssl x509 -noout -in cert.pem -issuer

# 查看持有者
openssl x509 -noout -in cert.pem -subject

# 有效期
openssl x509 -noout -in cert.pem -dates

# 以上全部
openssl x509 -noout -in cert.pem -issuer -subject -dates

# 哈希值
openssl x509 -noout -in cert.pem -hash

# MD5指纹
openssl x509 -noout -in cert.pem -fingerprint

如何导入/导出PKCS#12格式的证书?

PKCS#12格式的证书被许多程序使用,比如微软的IIS,这种证书文件的后缀通常是.pfx。
创建PKCS#12格式的证书,需要私钥和证书。转换时,你会被要求输入密码(可以为空)来对证书进行加密。

# 创建一个包含私钥的自签名证书
openssl req \
    -x509 -sha256 -nodes -days 365 \
    -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

# 将mycert.pem导出为PKCS#12格式的证书,mycert.pfx
openssl pkcs12 -export \
    -out mycert.pfx -in mycert.pem \
    -name "My Certificate"
如果你拿到PKCS#12格式的证书和它的密码(如果有的话),可以把它导出为标准的PEM格式。

# 无密码情况下
openssl pkcs12 -in mycert.pfx -out mycert.pem -nodes

# 有密码情况下
openssl pkcs12 -in mycert.pfx -out mycert.pem

证书验证

使用OpenSSL库可以验证授权机构颁发的证书

如何验证证书?

使用verify选项来验证证书。

openssl verify cert.pem

验证成功,会返回“OK”。

$ openssl verify mycert.pem
mycert.pem: /C=CN/ST=JS/L=WX/O=Internet Widgits Pty Ltd/CN=Calle Zhang
error 18 at 0 depth lookup:self signed certificate
OK

如果异常会看到错误消息,比如

证书过期,通常证书都是有有效期的,一般是一年:
error 10 at 0 depth lookup:certificate has expired

自签名证书:
error 18 at 0 depth lookup:self signed certificate

OpenSSL都认可哪些证书颁发机构?

在编译OpenSSL库时需要制定OpenSSL的文件目录(--openssldir参数指定),这个目录保存着认可的证书颁发机构信息。
默认的目录是/usr/local/ssl,很多操作系统会把它放到别处,比如/usr/share/ssl(Red Hat/Fedora),/etc/ssl(Gentoo),/usr/lib/ssl(Debian),/System/Library/OpenSSL(Macintosh OS X)。
使用version选项加上-d查看目录在什么位置

openssl version -d

这个目录下有个certs子目录,在certs里可能会有三种类型的文件:

  • 有一个名为cert.pem的大文件,里面包含了许多认可机构(比如VeriSign,Thawte)的证书。
  • 一些以.pem为后缀的小文件,每个文件包含一个认可机构的一个证书。
  • 一些奇怪名字的链接文件,比如052eae11.0,通常是指向.pem文件。这个文件名字的第一部分其实是.pem文件里证书的hash值,后缀是序列号,因为多个链接文件可以指向同一证书。以我的Gentoo系统为例,有个指向vsignss.pem的链接文件叫f73e89fd.0,可以肯定里面证书的哈希值就是这个文件名:

$ openssl x509 -noout -hash -in vsingss.pem f73e89fd 当OpenSSL要验证一个证书,它会查看cert.pem里面是否包含这个证书,如果没有再查看这个目录下是否存在以证书哈希值为名的文件,如果存在就验证通过。
有意思的是,有些程序(比如Sendmail)会在运行时让你指定你信任证书的存储位置。

如何让OpenSSL信任某个证书?

把这个证书放入上文说的certs目录下,然后创建一个以哈希值命名的链接文件,下面的脚本可以完成这样的任务:

#!/bin/sh
#
# usage: certlink.sh filename [filename ...]

for CERTFILE in $*; do
    # make sure file exists and is a valid cert
    test -f "$CERTFILE" || continue
    HASH=$(openssl x509 -noout -hash -in "$CERTFILE")
    test -n "$HASH" || continue

    # use lowest available iterator for symlink
    for ITER in 0 1 2 3 4 5 6 7 8 9; do
        test -f "${HASH}.${ITER}" && continue
        ln -s "$CERTFILE" "${HASH}.${ITER}"
        test -L "${HASH}.${ITER}" && break
    done
done

加密/解密

如何使用base64编码?

使用enc -base64选项

# 对文件file.txt里的内容进行base64编码
openssl enc -base64 -in file.txt

# 将编码结果输出到file.txt.enc
openssl enc -base64 -in file.txt -out file.txt.enc

通过命令行编码指定的字符串:

$ echo "encode me" | openssl enc -base64
ZW5jb2RlIG1lCg==

注意echo会在字符串结尾添加一个换行符,可以使用-n选项去除。当你对一些认证信息编码时,这点很重要。

$ echo -n "encode me" | openssl enc -base64
ZW5jb2RlIG1l

使用-d选项可以解码:

$ echo "ZW5jb2RlIG1lCg==" | openssl enc -base64 -d
encode me

如何简单的加密一个文件?

有时候我们只是想简单的通过密码加密一个文件,不想使用专业的工具,也不想创建私钥/证书之类的。
这是很简单,你需要记住密码以及使用的加密算法。
首先选一个加密算法,可以通过下面的方法列出可用的算法:

# ‘Cipher commands’下的列表
openssl -h

# 算法列表,每行一个
openssl list-cipher-commands
选完加密算法后,还要决定是否对加密后数据进行base64编码,base64编码后数据方便查看,不编码就是二进制的形式。

# 使用256位AES算法CBC模式,加密file.txt为file.enc。
openssl enc -aes-256-cbc -salt -in file.txt -out file.enc

# 对加密后数据进行base64编码(-a或-base64)
openssl enc -aes-256-cbc -a -salt -in file.txt -out file.enc
解密file.enc

# 解密二进制file.enc
openssl enc -d -aes-256-cbc -in file.enc

# 解密base64格式的
openssl enc -d -aes-256-cbc -a -in file.enc
如果你不想每次加解密时都输入密码,可以直接在命令中提供:

# 在命令行提供密码
openssl enc -aes-256-cbc -salt -in file.txt \
    -out file.enc -pass pass:mySillyPassword

# 在一个文件中提供密码
openssl enc -aes-256-cbc -salt -in file.txt \
    -out file.enc -pass file:/path/to/secret/password.txt

openssl 安装

openssl 没有windows安装包,不过可以通过其他平台下载:

  • https://slproweb.com/products/Win32OpenSSL.html
# 生成证书
# 在要存放证书的文件夹下打开命令行窗口(或者切换到目录)
# 输入下面命令生成证书:
openssl genrsa 1024 > key.pem

# 输入下面命令生成安全证书:
openssl req -x509 -new -key key.pem > key-cert.pem

参考文献

苏ICP备19018690号-1