谈谈https和证书

谈谈https和证书1 前言 本篇文章我们讲解下关于 https 及证书的相关知识 因为我发现不理解证书感觉很难理解 https 所以本篇会花大量的篇幅来讲证书 我们一开始会讲解一些相关概念帮助大家理解下 然后我们自己签发一个证书来理解这个过程 最后通过实例和抓包帮助大家理解 https 因为本篇文章有很多代码及配置文件相关

大家好,我是讯享网,很高兴认识大家。

1. 前言

本篇文章我们讲解下关于https及证书的相关知识,因为我发现不理解证书感觉很难理解https,所以本篇会花大量的篇幅来讲证书,我们一开始会讲解一些相关概念帮助大家理解下,然后我们自己签发一个证书来理解这个过程,最后通过实例和抓包帮助大家理解https。因为本篇文章有很多代码及配置文件相关,最好通过电脑打开查看,篇幅很长,感谢耐心。

2. 概念区分

见到https时就会有很多不知道的概念,我们这里来区分下:

HTTPS:https即为http及其下边一层的可靠的安全加密的传输协议(tls/ssl),它主要思想是传输的双发验证对端的证书是否可以通过(被信任),以此生成加密的密钥,通过此密钥加密传输的内容,后边会详解。

SSL:Secure Socket Layer, 安全套接字层,http层下新增加的这一层构成了https

TLS:Transport Layer Security,同样是为了保证数据安全的加密协议层,是SSL的增强版,SSL有1.0,2.0,3.0版本,TLS目前1.0,1.1,1.2,1.3,TLS的1.0版本就是SSL的3.0

Key:https中有公钥和私钥,用公钥加密的内容,可以使用私钥解密,反之亦然,不过我们平常所说的key文件是指私钥文件

CRT: certificate证书文件,是证书机构颁发的保证安全通信的文件,由域名、公司信息、序列号和签名信息等组成

CER:也是证书文件,和CRT相比只是缩写不同,CRT缩写常见于类uninx系统,CER缩写常见于windows系统

X.509:这里特指颁发的证书的格式,而其根据不同的编码格式分为PEM和DER:

  • PEM - Privacy Enhanced Mail,打开看文本格式,以"-----BEGIN…"开头, "-----END…"结尾,内容是BASE64编码.Apache和*NIX服务器偏向于使用这种编码格式,这种也是我们所常见的
  • DER - Distinguished Encoding Rules,打开是二进制格式,不可读.Java和Windows服务器偏向于使用这种编码格式

CSR:Certificate Signing Request 证书签名请求,里面包含公钥等个体信息,这个发给公证机构作为申请,通过这个公证机构颁发证书给你

CA:Catificate Authority 证书颁发机构,它的作用就是给各个用户签发证书等,比如说Symantec、Comodo、Godaddy、GolbalSign 和 Digicert等

openssl:相当于SSL的一个实现,如果把SSL规范看成OO中的接口,那么OpenSSL则认为是接口的实现,个人理解openssl是作为针对SSL/TLS的一个工具,包括对证书的解析,个人颁发,证书编码转化等

3. CA和证书颁发

使用https进行通信,就需要一个证书,那么证书哪里来,就是来自于CA(证书颁发机构)颁发。所谓证书就是比较有公信的机构颁发给你,然后你用他来进行通信,另外一端验证通过后就会信任你,进行信息通信。举例来说如果你的服务器没有证书,浏览器访问你的网址时,会提示不安全。

讯享网
那么如果有一个服务器,如何才能获取到证书呢,如果要从证书颁发机构申请的话,需要提供CSR文件及钱,然后机构就会颁发证书给你。如果你想要自己给自己颁发,只是用来本地玩玩,或者局域网各个机器之间的相互交流,便可以自己建立一个CA,使用这个CA来给自己颁发证书。我们下面以给自己颁发证书的全过程来描述下,我们使用openssl来进行构建。

CA角色也是需要一个自身的pair,pair包括key(private)和certificate,而最原始的被称为root pair,通常情况下,root CA 不会直接为服务器或者客户端签证,它们会先为自己生成几个中间 CA(intermediate CAs),这几个中间 CA 作为 root CA 的代表为服务器和客户端签证。自己实操的过程中其实也可以直接使用root pair来给服务器签发,为了演示全面,我们来使用intermediate CA来签发证书。

3.1 新建目录:

$ cd /etc/pki/ $ mkdir leap && cd leap $ mkdir ca && cd ca 

讯享网

3.2 设置root CA:

生成root key

讯享网$ mkdir root && cd root $ mkdir certs crl newcerts private $ openssl genrsa -aes256 -out private/leap_ca_key.pem 4096 Enter pass phrase for root_ca.key.pem: [pass] Verifying - Enter pass phrase for root_ca.key.pem: [passwd] $ chmod 400 private/leap_ca_key.pem 
HOME = . RANDFILE = .rand [ca] default_ca = ca_default [ca_default] dir = . certs = $dir/certs crl_dir = $dir/crl database = $dir/index.txt new_certs_dir = $dir/newcerts certificate = $dir/certs/%s_ca_cert.pem private_key = $dir/private/%s_ca_key.pem serial = $dir/serial crl = $dir/crl.pem x509_extensions = usr_cert name_opt = ca_default cert_opt = ca_default default_days = 3650 default_crl_days = 30 default_md = sha256 preserve = no policy = policy_match [policy_match] # The root CA should only sign intermediate certificates that match. # See the POLICY FORMAT section of `man ca`. countryName = match stateOrProvinceName = match organizationName = match 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] default_bits = 2048 default_keyfile = privkey.pem default_md = sha256 distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extensions to add to the self signed cert string_mask = utf8only [req_distinguished_name] countryName = Country Name (2 letter code) countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) organizationalUnitName = Organizational Unit Name (eg, section) commonName = Common Name (eg, your name or your server hostname) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 # Optionally, 修改下这里填写自己的相关信息 countryName_default = CN stateOrProvinceName_default = Beijing localityName_default = Beijing 0.organizationName_default = Leap organizationalUnitName_default = emailAddress_default = [req_attributes] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [usr_cert] basicConstraints = CA:FALSE nsComment = "OpenSSL Generated Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always [v3_ca] # Extensions for a typical CA (`man x509v3_config`). subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer:always basicConstraints = critical, CA:true [ 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 

自己使用的话,可以修改[req_distinguished_name]下的指定的内容为CA的相关信息

然后我们再建立cnf中需要的文件([ca_default]下):

讯享网$ touch index.txt $ echo 1000 > serial 

准备工作完成,我们来生成CA的root cert

$ openssl req -config openssl.cnf -new -x509 -days 3650 -sha256 \ -key private/leap_ca_key.pem -extensions v3_ca \ -out certs/leap_ca_cert.pem Enter pass phrase for private/leap_ca_key.pem: Can't load .rand into RNG 8816:error:2406F079:random number generator:RAND_load_file:Cannot open file:crypto/rand/randfile.c:98:Filename=.rand 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) [CN]: State or Province Name (full name) [Beijing]: Locality Name (eg, city) [Beijing]: Organization Name (eg, company) [Leap]: Organizational Unit Name (eg, section) []:LeapCA Common Name (eg, your name or your server's hostname) []:leap.cn Email Address []: 

这里会出现交互界面,让你来填写,上面有一部分我们已经设定了默认值,除此之外我们需要设定其他的值,比较要注意的是Common Name一般就是指你的域名或者host名

然后我们验证看下生成root证书:

讯享网$ openssl x509 -noout -text -in certs/leap_ca_cert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 7d:f5:69:17:10:8b:67:13:83:44:a1:71:c7:fb:05:8a:f1:c5:47:59 Signature Algorithm: sha256WithRSAEncryption Issuer: C = CN, ST = Beijing, L = Beijing, O = Leap, OU = LeapCA, CN = leap.cn Validity Not Before: Oct 25 07:05:32 2021 GMT Not After : Oct 23 07:05:32 2031 GMT Subject: C = CN, ST = Beijing, L = Beijing, O = Leap, OU = LeapCA, CN = leap.cn Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: ... Signature Algorithm: sha256WithRSAEncryption 2c:e9:ff:57:2c:ca:4a:e0:bc:35:dc:e4:13:89:16:6b:4c:44: d8:32:d7:cd:fe:41:88:76:eb:c9:35:92:34:20:98:a2:f0:4d: 23:f5:1c:80:79:75:14:e6:a0: ... 
  • 数字签名(Signature Algorithm)
  • 有效时间(Validity)
  • 主体(Issuer)
  • 公钥(Public Key)
  • X509v3 扩展,openssl config 中配置了 v3_ca,所以会生成此项

3.3 设置intermediate CA:

现在已经有了root pair,已经可以证书发放了,不过还是通过中间(intermediate)pair作为root pair的代理来颁发证书。

新建目录及生成intermediate key:

$ ls certs crl newcerts openssl.cnf private $ pwd /etc/pki/leap/ca/root $ cd .. $ mkdir intermediate && cd intermediate $ mkdir certs crl csr newcerts private $ openssl genrsa -aes256 \ -out private/leap_intermediate_key.pem 4096 $ chmod 400 private/leap_intermediate_key.pem 

生成intermediate key

最开始还是要设置配置文件,将上一个openssl.cnf拷贝到intermediate目录下,我们修改一下:

讯享网# ... [ca_default] # ... certificate = $dir/certs/%s_intermediate_cert.pem private_key = $dir/private/%s_intermediate_key.pem # ... policy = policy_loose # ... # 增加下边 [ server_cert ] # Extensions for server certificates (`man x509v3_config`). basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth, clientAuth # 如签发的证书单向认证,只需要serverAuth 

同样也还是建立需要的文件:

$ touch index.txt $ echo 1000 > serial 

生成csr文件:

讯享网$ openssl req -config openssl.cnf -new -sha256 \ -key private/leap_intermediate_key.pem \ -out csr/leap_intermediate_csr.pem 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) [CN]: State or Province Name (full name) [Beijing]: Locality Name (eg, city) [Beijing]: Organization Name (eg, company) [Leap]: Organizational Unit Name (eg, section) []:LeapIntermediate Common Name (eg, your name or your server's hostname) []:leap.sub.cn Email Address []: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:[passwd] # passwd An optional company name []: 

这里生成csr文件需要填写内容和之前很相似,除了需要设置csr的一些信息,要注意的是CommanName不要和CA一样。

接下来通过root pair来为intermediate pair生成证书:

# 用到刚刚生成csr文件 $ cd ../root $ openssl ca -config openssl.cnf -extensions v3_intermediate_ca \ -keyfile private/leap_ca_key.pem \ -cert certs/leap_ca_cert.pem \ -days 3650 -notext -md sha256 \ -in ../intermediate/csr/leap_intermediate_csr.pem \ -out ../intermediate/certs/leap_intermediate_cert.pem # ... Signature ok Certificate Details: Serial Number: 4096 (0x1000) Validity Not Before: Oct 26 08:54:20 2021 GMT Not After : Oct 24 08:54:20 2031 GMT Subject: countryName = CN stateOrProvinceName = Beijing organizationName = Leap organizationalUnitName = LeapIntermediate commonName = leap.sub.cn # ... Certificate is to be certified until Oct 24 08:54:20 2031 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 Data Base Updated 

表示生成成功,看下index.txt多一条记录

讯享网V 0Z 1000 unknown /C=CN/ST=Beijing/O=Leap/OU=LeapIntermediate/CN=leap.sub.cn 

再来验证下生成的证书:

$ openssl verify -CAfile certs/leap_ca_cert.pem \ ../intermediate/certs/leap_intermediate_cert.pem ../intermediate/certs/leap_intermediate_cert.pem: OK 

3.4 创建证书链:

浏览器在验证中间证书的时候,同时也会去验证它的上一级证书是否靠谱,创建证书链,将 root cert 和 intermediate cert 合并到一起,可以让浏览器一并验证:

讯享网$ cat ../intermediate/certs/leap_intermediate_cert.pem \ certs/leap_ca_cert.pem > ../intermediate/certs/leap_ca_chain_cert.pem $ chmod 444 ../intermediate/certs/leap_ca_chain_cert.pem 

3.5 使用intermediate pair为客户端和服务器创建证书

CA的角色既然已经创建完成了,下一步就是为通信的双方创建证书了,有一点要明确的是tls/ssl分为双向认证和单向认证。如果双向认证,客户端和服务端都要有自己的证书,如果单向认证,只需要服务端有自己的证书,平常浏览器访问就是单向认证,为什么单向认证?其实原因也很简单,总不能给每个人(浏览器端)都颁发一个证书吧,所以https这里采用的是单向认证。这里客户端和服务器都生成自己的证书。

为客户端生成pair:

$ cd .. $ pwd /etc/pki/leap/ca $ mkdir leap.client.cn # 生成key $ openssl genrsa -aes256 -out leap.client.cn/leap_client_key.pem 2048 # 生成csr,Common Name设置为leap.client.cn $ openssl req -config intermediate/openssl.cnf \ -key leap.client.cn/leap_client_key.pem \ -new -sha256 -out leap.client.cn/leap_client_csr.pem # 使用intermediate pair为client生成cert $ cd intermediate $ openssl ca -config openssl.cnf \ -extensions server_cert -days 375 -notext -md sha256 \ -keyfile private/leap_intermediate_key.pem \ -cert certs/leap_intermediate_cert.pem \ -in ../leap.client.cn/leap_client_csr.pem \ -out ../leap.client.cn/leap_client_cert.pem 

为服务端生成pair:

讯享网$ cd .. $ pwd /etc/pki/leap/ca $ mkdir leap.server.cn # 生成key $ openssl genrsa -aes256 -out leap.server.cn/leap_server_key.pem 2048 # 生成csr, Common Name设置为leap.server.cn $ openssl req -config intermediate/openssl.cnf \ -key leap.server.cn/leap_server_key.pem \ -new -sha256 -out leap.server.cn/leap_server_csr.pem # 使用intermediate pair为server生成cert $ cd intermediate $ openssl ca -config openssl.cnf \ -extensions server_cert -days 375 -notext -md sha256 \ -keyfile private/leap_intermediate_key.pem \ -cert certs/leap_intermediate_cert.pem \ -in ../leap.server.cn/leap_server_csr.pem \ -out ../leap.server.cn/leap_server_cert.pem 

到这里我们就为server和client分别生成了pair,接下来我们就通过实例来验证下生成的证书是否正确。

4. 实例看双向认证

4.1 准备

首先第一步将生成证书链文件,服务器的key和cert文件,客户端的key和cert文件拷贝到工程中以备使用,新建一个客户端程序文件和服务端程序文件,结构如图所示:

证书文件我给重命名了下(去掉leap_前缀),这里使用因为我们private key都是加了密的(没有加密忽略此步骤),所以使用时候需要解密才能使用,指令为:

openssl rsa -in leap_server_key.pem -out server_key.pem -passin pass:[your passwd] openssl rsa -in leap_client_key.pem -out client_key.pem -passin pass:[your passwd] 

4.2 服务端代码

讯享网package main import ( // ...(略) ) func main() { 
    pool := x509.NewCertPool() if ca, e := ioutil.ReadFile("ca_chain_cert.pem"); e != nil { 
    log.Fatal("ReadFile: ", e) } else { 
    pool.AppendCertsFromPEM(ca) } s := &http.Server{ 
    Addr: ":443", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
    fmt.Fprintf(w, "Hello World!\n") }), TLSConfig: &tls.Config{ 
    ClientCAs: pool, ClientAuth: tls.RequireAndVerifyClientCert, }, } e := s.ListenAndServeTLS("server_cert.pem", "server_key.pem") if e != nil { 
    log.Fatal("ListenAndServeTLS: ", e) } } 

程序也比较简单,初始化一个http.Server,进行一些配置,里面初始化CA,然后设置cert和key并监听启动服务

4.3 客户端代码

package main import ( // ...(略) ) func main() { 
    pool := x509.NewCertPool() if ca, e := ioutil.ReadFile("ca_chain_cert.pem"); e != nil { 
    log.Fatal("ReadFile: ", e) } else { 
    pool.AppendCertsFromPEM(ca) } pair, e := tls.LoadX509KeyPair("client_cert.pem", "client_key.pem") if e != nil { 
    log.Fatal("LoadX509KeyPair:", e) } client := &http.Client{ 
    Transport: &http.Transport{ 
    TLSClientConfig: &tls.Config{ 
    RootCAs: pool, Certificates: []tls.Certificate{ 
   pair}, }, }} resp, e := client.Get("https://leap.server.cn") if e != nil { 
    log.Fatal("http.Client.Get: ", e) } defer resp.Body.Close() io.Copy(os.Stdout, resp.Body) } 

代码比较类似,新建client对象,将ca,cert,key等进行配置,不过要注意的一点是域名要使用服务端生成证书里面的域名: leap.server.cn,即我们在生成csr的时候Common Name。

本例中跑在一台机器,所以需要设置hosts文件:

讯享网$ vim /etc/hosts 127.0.0.1 leap.server.cn 

4.4 运行

然后我们来运行下:

# 启动服务器 $ go build tls_server.go $ ./tls_server # 启动客户端 $ go build tls_client.go $ ./tls_client 2021/10/27 19:15:45 http.Client.Get: Get "https://leap.server.cn": x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0 

发现启动客户端时报错,原因是因为go 1.15 版本开始废弃 CommonName,推荐使用 SAN 证书。 如果想兼容之前的方式,需要设置环境变量 GODEBUG 为 x509ignoreCN=0。两种解决方案,要么重新生成SAN证书,要么就是设置环境变量 GODEBUG 为 x509ignoreCN=0,首先第二种解决方案如下:

讯享网$ GODEBUG=x509ignoreCN=0 ./tls_client Hello World! 

不过浏览器使用的话,也会验证服务端证书的这个字段,所以还是重新生成下服务端的证书,需要修改intermediate/openssl.conf下的[ server_cert ]下增加一个item并增加[alt_names]的group:

[ server_cert ] subjectAltName = @alt_names [alt_names] DNS.1 = leap.server.cn 

用这个cnf重新执行生成服务端证书的步骤,这样就不需要加GODEBUG了:

讯享网$ ./tls_client Hello World! 

好的验证成功,已完成。

5. 抓包看单向认证

我们平时使用的https还是单向认证的,就是平常浏览器访问服务器这种情况,单向认证只是比双向认证少服务端验证客户端证书的步骤,借此来抓包,详细的分析下https的协议。

5.1 准备工作

  • 修改hosts,使得leap.server.cn的ip地址是运行服务端程序的机器
  • 重命名证书链后缀名为crt,这样windows系统可以识别此文件
  • 右键点击选择安装证书->本地计算机->将所有证书都放入下列存储->浏览选择”受信任的根证书颁发机构”->下一页->完成

    我们来检查下,打开浏览器(chrome为例)设置->隐私设置和安全性->安全->管理证书,就可以看到证书

5.2 服务器代码重写

服务端的程序还需要修改下,因为之前那个服务端程序是会去验证客户端的,需要写一个不验证客户端证书的服务端程序,代码超级简单:

func handler(w http.ResponseWriter, r *http.Request) { 
    io.WriteString(w, "https world!") } func main() { 
    http.HandleFunc("/", handler) if err := http.ListenAndServeTLS(":443", "server_cert.pem", "server_key.pem", nil); err != nil { 
    log.Fatal("ListenAndServe:", err) } } 

最后使用浏览器访问下:

访问成功,网址那里也有一个锁头表示此网站是安全的。

5.3 wireshark抓包看

接下来用wireshark抓包看下先:

192.168.77.1是客户端浏览器,192.168.77.133是服务器, 简单过下流程:

首先完成tcp握手后,client发起Client hello,这里会传送客户端支持的tls版本,一个随机数(后期生成密钥使用),支持的加密算法,支持的压缩算法等

服务端收到请求后,发送Service Hello,这里包含选择的tls版本,服务器生成的随机数(后期生成密钥使用),选中的加密算法,选中的压缩算法。

然后服务端会发送证书给客户端,发送使用证书签名的握手信息等

客户端验证证书完成,发送使用加密信息发送的通知,并结束

之后就是客户端请求服务端的消息了(黄色部分)

这里抓包的tls是1.3版本,并未深入讲解,着重讲解两个点:

  • a. tls握手阶段,会根据随机值等协商一个对称加密的密钥,后面的通信都是使用这个密钥来加密。总结来说握手阶段会用到服务端的非对称密钥传输协商,协商出对称密钥用于后期的数据加密
  • b. 客户端验证证书环节,是怎样来验证呢?

    首先浏览器读取证书中的证书所有者、有效期等信息进行校验,校验证书的网站域名是否与证书颁发的域名一致,校验证书是否在有效期内等等

    然后查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发

    最后就是验证证书的完整性和正确性了,我们前面介绍过:
讯享网$ openssl verify -CAfile certs/leap_ca_cert.pem \ ../intermediate/certs/leap_intermediate_cert.pem ../intermediate/certs/leap_intermediate_cert.pem: OK 

不过这里做了什么呢?我们仔细看下证书的部分分为摘要信息和签名信息(Signature),当在签发的时候,CA会把持有者的公钥、用途、颁发者、有效时间等信息进行Hash计算,得到一个Hash值,Hash值使用CA的私钥加密,生成Certificate Signature,也就是签名信息。这样当客户端验证的时候使用CA的公钥解密,并将服务端的公钥的摘要信息使用Hash计算判断二者是否相等,从而能够验证证书的完整性和正确性

6. 总结

整体来说我们把https和证书颁发这块知识讲解了下,https使用tls/ssl来进行加密,其中https分为双向验证和单向验证,双向验证比如说银行的一些交易客户这边需要U盾或者其他就是验证客户端的证书,而我们平常浏览器访问不需要验证客户端就是单向认证。篇幅原因tls详细没有展开讲,感谢阅读

7.ref

  • https://www.barretlee.com/blog/2016/04/24/detail-about-ca-and-certs/
  • https://zq99299.github.io/note-book2/http-protocol/
小讯
上一篇 2025-04-11 21:09
下一篇 2025-03-09 14:21

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/128769.html