45fan.com - 路饭网

搜索: 您的位置主页 > 网络频道 > 阅读资讯:openssl简介之前言的详细介绍

openssl简介之前言的详细介绍

2016-08-25 06:17:12 来源:www.45fan.com 【

openssl简介之前言的详细介绍

openssl简介--前言

发信站:BBS水木清华站(FriNov1020:19:302000)



不久前接到有关ssl的活,结果找遍中文网站资料实在奇缺。感觉是好象现在国内做这个技术的人不多所有有兴趣写点东西来介绍一下。

我使用的ssl的toolkit是openssl就用openssl做例子来讲解
openssl实在太大了,指令也多,API也多,更严重的是它的API没有说明。我打算漫漫说清楚其主要指令的用法,主要API的中文说明,以及使用/编程的方法。

工作量很大,因为我接触它也没几个月,现在大概完成了1/10吧,先把目前自己的一些心得,找到的资料和一些翻译出来的东西贴出来,希望对研究ssl的人有帮助




openssl简介-证书
http://bbs.chinaunix.net/forum/viewtopic.php?p=3161562#3161585

openssl简介-加密算法
http://bbs.chinaunix.net/forum/viewtopic.php?p=3161562#3161685

openssl简介-协议
http://bbs.chinaunix.net/forum/viewtopic.php?p=3161562#3161727

openssl简介-入门
http://bbs.chinaunix.net/forum/viewtopic.php?p=3161562#3162073

openssl简介-指令verify
http://bbs.chinaunix.net/forum/viewtopic.php?p=3161562#3173096

openssl简介-指令asn1parse
http://bbs.chinaunix.net/forum/viewtopic.php?p=3161562#3173120

openssl简介-指令ca
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173126#3173126

openssl简介-指令cipher
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173132#3173132

openssl简介-指令dgst
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173136#3173136

openssl简介-指令dhparam
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173142#3173142

openssl简介-指令enc
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173146#3173146

openssl简介-指令gendsa
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173149#3173149

openssl简介-指令genrsa
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173152#3173152

openssl简介-指令passwd
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173154#3173154

openssl简介-指令pkcs7
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173156#3173156

openssl简介-指令rand
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173158#3173158

openssl简介-指令req
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173162#3173162

openssl简介-指令rsa
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173164#3173164

openssl简介-指令rsautl
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173168#3173168

openssl简介-指令s_client
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173171#3173171

openssl简介-指令s_server
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173175#3173175

openssl简介-指令sess_id
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173176#3173176

openssl简介-指令speed
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173178#3173178

openssl简介-指令version
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173181#3173181

openssl简介-指令x509
http://bbs.chinaunix.net/forum/viewtopic.php?p=3173188#3173188



标题:openssl简介--证书

发信站:BBS水木清华站(FriNov1020:29:282000)

引用请指明原作译者fordesign@21cn.com

二证书



证书就是数字化的文件,里面有一个实体(网站,个人等)的公共密钥和其他的属性,如名称等。该公共密钥只属于某一个特定的实体,它的作用是防止一个实体假装成另外一个实体。

证书用来保证不对称加密算法的合理性。想想吧,如果没有证书记录,那么假设某俩人A与B的通话过程如下:

这里假设A的publickey是K1,privatekey是K2,B的publickey是K3,privatekey是K4

xxxxxx(kn)表示用kn加密过的一段文字xxxxxx

A-----〉hello(plaintext)-------------〉B
A〈---------hello(plaintext)〈---------B
A〈---------Bspublickey〈------------B
A---------〉spublickey(K1)--------〉B
......



如果C想假装成B,那么步骤就和上面一样。
A-----〉hello(plaintext)-------------〉C
A〈---------hello(plaintext)〈---------C

注意下一步,因为A没有怀疑C的身份,所以他理所当然的接受了C的publickey,并且使用这个key来继续下面的通信。

A〈---------Cspublickey〈------------C
A---------〉Aspublickey(K1)--------〉C
......

这样的情况下A是没有办法发觉C是假的。如果A在通话过程中要求取得B的证书,并且验证证书里面记录的名字,如果名字和B的名字不符合,就可以发现对方不是B.验证B的名字通过再从证书里面提取B的公用密钥,继续通信过程。


那么,如果证书是假的怎么办?或者证书被修改过了怎么办?慢慢看下来吧。


证书最简单的形式就是只包含有证书拥有者的名字和公用密钥。当然现在用的证书没这么简单,里面至少还有证书过期的deadline,颁发证书的机构名称,证书系列号,和一些其他可选的信息。最重要的是,它包含了证书颁发机构(certificationauthority简称CA)的签名信息。

我们现在常用的证书是采用X.509结构的,这是一个国际标准证书结构。任何遵循该标准的应用程序都可以读,写X509结构的证书。

通过检查证书里面的CA的名字,和CA的签名,就知道这个证书的确是由该CA签发的然后,你就可以简单证书里面的接收证书者的名字,然后提取公共密钥。这样做建立的基础是,你信任该CA,认为该CA没有颁发错误的证书。

CA是第三方机构,被你信任,由它保证证书的确发给了应该得到该证书的人。CA自己有一个庞大的publickey数据库,用来颁发给不同的实体。

这里有必要解释一下,CA也是一个实体,它也有自己的公共密钥和私有密钥,否则怎么做数字签名?它也有自己的证书,你可以去它的站点down它的证书得到它的公共密钥。

一般CA的证书都内嵌在应用程序中间。不信你打开你的IE,在internet选项里面选中"内容",点击"证书",看看那个"中间证书发行机构"和"委托根目录发行机构",是不是有一大堆CA的名称?也有时CA的证书放在安全的数据库里面。

当你接受到对方的证书的时候,你首先会去看该证书的CA,然后去查找自己的CA证书数据库,看看是否找的到,找不到就表示自己不信任该CA,那么就告吹本次连接。找到了的话就用该CA的证书里面的公用密钥去检查CA在证书上的签名。

这里又有个连环的问题,我怎么知道那个CA的证书是属于那个CA的?人家不能造假吗?

解释一下吧。CA也是分级别的。最高级别的CA叫RootCAs,其他cheap一点的CA的证书由他们来颁发和签名。这样的话,最后的保证就是:我们信任RootCAs.那些有RootCAs签名过的证书的CA就可以来颁发证书给实体或者其他CA了。

你不信任RootCAs?人民币由中国人民银行发行,运到各个大银行,再运到地方银行,你从地方银行取人民币的时候不信任发行它的中国人民银行吗?RootCAs都是很权威的机构,没有必要担心他们的信用。

那RootCAs谁给签名?他们自己给自己签名,叫自签名.

说了这么多,举个certificate的例子吧,对一些必要的item解释一下。

CertificateExample
Certificate:
Data:
Version:1(0x0)
SerialNumber://系列号
02:41:00:00:16
SignatureAlgorithm:md2WithRSAEncryption//CA同志的数字签名的算法
Issuer:C=US,O=RSADataSecurity,Inc.,OU=Commercial//CA自报家门
Certification
Authority
Validity
NotBefore:Nov418:58:341994GMT//证书的有效期
NotAfter:Nov318:58:341999GMT
Subject:C=US,O=RSADataSecurity,Inc.,OU=Commercial
CertificationAuthority
SubjectPublicKeyInfo:
PublicKeyAlgorithm:rsaEncryption
RSAPublicKey:(1000bit)
Modulus(1000bit):
00:a4:fb:81:62:7b:ce:10:27:dd:e8:f7:be:6c:6e:
c6:70:99:db:b8:d5:05:03:69:28:82:9c:72:7f:96:
3f:8e:ec:ac:29:92:3f:8a:14:f8:42:76:be:bd:5d:
03:b9:90:d4:d0:bc:06:b2:51:33:5f:c4:c2:bf:b6:
8b:8f:99:b6:62:22:60:dd:db:df:20:82:b4:ca:a2:
2f:2d:50:ed:94:32:de:e0:55:8d:d4:68:e2:e0:4c:
d2:cd:05:16:2e:95:66:5c:61:52:38:1e:51:a8:82:
a1:c4:ef:25:e9:0a:e6:8b:2b:8e:31:66:d9:f8:d9:
fd:bd:3b:69:d9:eb
Exponent:65537(0x10001)
SignatureAlgorithm:md2WithRSAEncryption
76:b5:b6:10:fe:23:f7:f7:59:62:4b:b0:5f:9c:c1:68:bc:49:
bb:b3:49:6f:21:47:5d:2b:9d:54:c4:00:28:3f:98:b9:f2:8a:
83:9b:60:7f:eb:50:c7:ab:05:10:2d:3d:ed:38:02:c1:a5:48:
d2:fe:65:a0:c0:bc:ea:a6:23:16:66:6c:1b:24:a9:f3:ec:79:
35:18:4f:26:c8:e3:af:50:4a:c7:a7:31:6b:d0:7c:18:9d:50:
bf:a9:26:fa:26:2b:46:9c:14:a9:bb:5b:30:98:42:28:b5:4b:
53:bb:43:09:92:40:ba:a8:aa:5a:a4:c6:b6:8b:57:4d:c5

其实这是我们看的懂的格式的证书内容,真正的证书都是加密过了的,如下:



-----BEGINCERTIFICATE-----

MIIDcTCCAtqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCQ0gx

EjAQBgNVBAgTCWd1YW5nZG9uZzESMBAGA1UEBxMJZ3Vhbmd6aG91MREwDwYDVQQK

Ewhhc2lhaW5mbzELMAkGA1UECxMCc3cxDjAMBgNVBAMTBWhlbnJ5MSEwHwYJKoZI

hvcNAQkBFhJmb3JkZXNpZ25AMjFjbi5jb20wHhcNMDAwODMwMDc0MTU1WhcNMDEw

ODMwMDc0MTU1WjCBiDELMAkGA1UEBhMCQ0gxEjAQBgNVBAgTCWd1YW5nZG9uZzES

MBAGA1UEBxMJZ3Vhbmd6aG91MREwDwYDVQQKEwhhc2lhaW5mbzELMAkGA1UECxMC

c3cxDjAMBgNVBAMTBWhlbnJ5MSEwHwYJKoZIhvcNAQkBFhJmb3JkZXNpZ25AMjFj

bi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMDYArTAhLIFacYZwP30

Zu63mAkgpAjVHaIsIEJ6wySIZl2THEHjJ0kS3i8lyMqcl7dUFcAXlLYi2+rdktoG

jBQMOtOHv1/cmo0vzuf38+NrAZSZT9ZweJfIlp8W9uyz8Dv5hekQgXFg/l3L+HSx

wNvQalaOEw2nyf45/np/QhNpAgMBAAGjgegwgeUwHQYDVR0OBBYEFKBL7xGeHQSm

ICH5wBrOiqNFiildMIG1BgNVHSMEga0wgaqAFKBL7xGeHQSmICH5wBrOiqNFiild

oYGOpIGLMIGIMQswCQYDVQQGEwJDSDESMBAGA1UECBMJZ3Vhbmdkb25nMRIwEAYD

VQQHEwlndWFuZ3pob3UxETAPBgNVBAoTCGFzaWFpbmZvMQswCQYDVQQLEwJzdzEO

MAwGA1UEAxMFaGVucnkxITAfBgkqhkiG9w0BCQEWEmZvcmRlc2lnbkAyMWNuLmNv

bYIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAGQa9HK2mixM7ML7

0jZr1QJUHrBoabX2AbDchb4Lt3qAgPOktTc3F+K7NgB3WSVbdqC9r3YpS23RexU1

aFcHihDn73s+PfhVjpT8arC1RQDg9bDPvUUYphdQC0U+HF72/CvxGCTqpnWiqsgw

xqeog0A8H3doDrffw8Zb7408+Iqf

-----ENDCERTIFICATE-----



证书都是有寿命的。就是上面的那个NotBefore和NotAfter之间的日子。过期的证书,如果没有特殊原因,都要摆在证书回收列(certificaterevocationlist)里面.证书回收列,英文缩写是CRL.比如一个证书的key已经被破了,或者证书拥有者没有权力再使用该证书,该证书就要考虑作废。CRL详细记录了所有作废的证书。

CRL的缺省格式是PEM格式。当然也可以输出成我们可以读的文本格式。下面有个CRL的例子。



-----BEGINX509CRL-----

MIICjTCCAfowDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMxIDAeBgNVBAoT

F1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2VydmVy

IENlcnRpZmljYXRpb24gQXV0aG9yaXR5Fw05NTA1MDIwMjEyMjZaFw05NTA2MDEw

MDAxNDlaMIIBaDAWAgUCQQAABBcNOTUwMjAxMTcyNDI2WjAWAgUCQQAACRcNOTUw

MjEwMDIxNjM5WjAWAgUCQQAADxcNOTUwMjI0MDAxMjQ5WjAWAgUCQQAADBcNOTUw

MjI1MDA0NjQ0WjAWAgUCQQAAGxcNOTUwMzEzMTg0MDQ5WjAWAgUCQQAAFhcNOTUw

MzE1MTkxNjU0WjAWAgUCQQAAGhcNOTUwMzE1MTk0MDQxWjAWAgUCQQAAHxcNOTUw

MzI0MTk0NDMzWjAWAgUCcgAABRcNOTUwMzI5MjAwNzExWjAWAgUCcgAAERcNOTUw

MzMwMDIzNDI2WjAWAgUCQQAAIBcNOTUwNDA3MDExMzIxWjAWAgUCcgAAHhcNOTUw

NDA4MDAwMjU5WjAWAgUCcgAAQRcNOTUwNDI4MTcxNzI0WjAWAgUCcgAAOBcNOTUw

NDI4MTcyNzIxWjAWAgUCcgAATBcNOTUwNTAyMDIxMjI2WjANBgkqhkiG9w0BAQIF

AAN+AHqOEJXSDejYy0UwxxrH/9+N2z5xu/if0J6qQmK92W0hW158wpJg+ovV3+wQ

wvIEPRL2rocL0tKfAsVq1IawSJzSNgxG0lrcla3MrJBnZ4GaZDu4FutZh72MR3Gt

JaAL3iTJHJD55kK2D/VoyY1djlsPuNh6AEgdVwFAyp0v

-----ENDX509CRL-----





下面是文本格式的CRL的例子。

ThefollowingisanexampleofaCRLintextformat:

issuer=/C=US/O=RSADataSecurity,Inc./OU=SecureServerCertification

Authority

lastUpdate=May202:12:261995GMT

nextUpdate=Jun100:01:491995GMT

revoked:serialNumber=027200004CrevocationDate=May202:12:261995GMT

revoked:serialNumber=0272000038revocationDate=Apr2817:27:211995GMT

revoked:serialNumber=0272000041revocationDate=Apr2817:17:241995GMT

revoked:serialNumber=027200001ErevocationDate=Apr800:02:591995GMT

revoked:serialNumber=0241000020revocationDate=Apr701:13:211995GMT

revoked:serialNumber=0272000011revocationDate=Mar3002:34:261995GMT

revoked:serialNumber=0272000005revocationDate=Mar2920:07:111995GMT

revoked:serialNumber=024100001FrevocationDate=Mar2419:44:331995GMT

revoked:serialNumber=024100001ArevocationDate=Mar1519:40:411995GMT

revoked:serialNumber=0241000016revocationDate=Mar1519:16:541995GMT

revoked:serialNumber=024100001BrevocationDate=Mar1318:40:491995GMT

revoked:serialNumber=024100000CrevocationDate=Feb2500:46:441995GMT

revoked:serialNumber=024100000FrevocationDate=Feb2400:12:491995GMT

revoked:serialNumber=0241000009revocationDate=Feb1002:16:391995GMT

revoked:serialNumber=0241000004revocationDate=Feb117:24:261995GMT



总结一下X.509证书是个什么东东吧。它实际上是建立了公共密钥和某个实体之间联系的数字化的文件。它包含的内容有:

版本信息,X.509也是有三个版本的。

系列号
证书接受者名称
颁发者名称
证书有效期
公共密钥
一大堆的可选的其他信息
CA的数字签名

证书由CA颁发,由CA决定该证书的有效期,由该CA签名。每个证书都有唯一的系列号。证书的系列号和证书颁发者来决定某证书的唯一身份。

openssl有四个验证证书的模式。你还可以指定一个callback函数,在验证证书的时候会自动调用该callback函数。这样可以自己根据验证结果来决定应用程序的行为。具体的东西在以后的章节会详细介绍的。

openssl的四个验证证书模式分别是:

SSL_VERIFY_NONE:完全忽略验证证书的结果。当你觉得握手必须完成的话,就选用这个选项。其实真正有证书的人很少,尤其在中国。那么如果SSL运用于一些免费的服务,比如email的时候,我觉得server端最好采用这个模式。

SSL_VERIFY_PEER:希望验证对方的证书。不用说这个是最一般的模式了.对client来说,如果设置了这样的模式,验证server的证书出了任何错误,SSL握手都告吹.对server来说,如果设置了这样的模式,client倒不一定要把自己的证书交出去。如果client没有交出证书,server自己决定下一步怎么做。

SSL_VERIFY_FAIL_IF_NO_PEER_CERT:这是server使用的一种模式,在这种模式下,server会向client要证书。如果client不给,SSL握手告吹。

SSL_VERIFY_CLIENT_ONCE:这是仅能使用在sslsessionrenegotiation阶段的一种方式。什么是SSLsessionrenegotiation?以后的章节再解释。我英文差点,觉得这个词组也很难翻译成相应的中文。以后的文章里,我觉得很难直接翻译的单词或词组,都会直接用英文写出来。如果不是用这个模式的话,那么在regegotiation的时候,client都要把自己的证书送给server,然后做一番分析。这个过程很消耗cpu时间的,而这个模式则不需要client在regotiation的时候重复送自己的证书了。


wingger 回复于:2005-01-07 09:47:41

标题:openssl简介--加密算法

发信站:BBS水木清华站(FriNov1020:24:102000)

引用请指明原作/译者fordesign@21cn.com



一加密算法的一些常识


要理解ssl先要知道一些加密算法的常识.


加密算法很容易理解啦,就是把明文变成人家看不懂的东西,然后送给自己想要的送到的地方,接收方用配套的解密算法又把密文解开成明文,这样就不怕在路世上如果密文给人家截获而泄密。

加密算法有俩大类,第一种是不基于KEY的,举个简单的例子,我要加密"fordesign"这么一串字符,就把每个字符都变成它的后一个字符,那么就是"gpseftjhm"了,这样的东西人家当然看不明白,接收方用相反的方法就可以得到原文。当然这只是个例子,现在应该没人用这么搞笑的加密算法了吧。

不基于KEY的加密算法好象一直用到了计算机出现。我记得古中国军事机密都是用这种方式加密的。打战的时候好象军队那些电报员也要带着密码本,也应该是用这种方式加密的。这种算法的安全性以保持算法的保密为前提。

这种加密算法的缺点太明显了,就是一旦你的加密算法给人家知道,就肯定挂。日本中途岛惨败好象就是密码给老米破了。设计一种算法是很麻烦的,一旦给人破了就没用了,这也忑浪费。

我们现在使用的加密算法一般是基于key的,也就是说在加密过程中需要一个key,用这个key来对明文进行加密。这样的算法即使一次被破,下次改个key,还可以继续用。

key是一个什么东西呢?随便你,可以是一个随机产生的数字,或者一个单词,啥都行,只要你用的算法认为你选来做key的那玩意合法就行。

这样的算法最重要的是:其安全性取决于key,一般来说取决于key的长度。也就是说应该保证人家在知道这个算法而不知道key的情况下,破解也相当困难。其实现在常用的基于KEY的加密算法在网络上都可以找到,很多革命同志(都是老外)都在想办法破解基于key的加密算法又包括俩类:对称加密和不对称加密。对称加密指的是双方使用完全相同的key,最常见的是DES.DES3,RC4等。对称加密算法的原理很容易理解,通信一方用KEK加密明文,另一方收到之后用同样的KEY来解密就可以得到明文。

不对称加密指双方用不同的KEY加密和解密明文,通信双方都要有自己的公共密钥和私有密钥。举个例子比较容易理解,我们们假设通信双方分别是A,B.
A,拥有KEY_A1,KEY_A2,其中KEY_A1是A的私有密钥,KEY_A2是A的公共密钥。
B,拥有KEY_B1,KEY_B2,其中KEY_B1是B的私有密钥,KEY_B2是B的公共密钥。

公共密钥和私有密钥的特点是,经过其中任何一把加密过的明文,只能用另外一把才能够解开。也就是说经过KEY_A1加密过的明文,只有KEY_A2才能够解密,反之亦然。

通信过程如下:

A-------->;KEY_A2------------>;B
A<--------KEY_B2<------------A

这个过程叫做公共密钥交换,老外管这叫keyexchange.之后A和B就分别用对方的公共密钥加密,用自己的私有密钥解密。

一般公共密钥是要发布出去的,然后你通过自己的私有密钥加密明文,人家用你的公共密钥解密,如果能解开,那么说明你是加密人,这就是SSL使用的验证机制。

常用的不对称加密一般有RSA,DSA,DH等。我们一般使用RSA.

数字签名也是不对称加密算法的一个重要应用,理解它对于理解SSL很重要的,放在这里一起介绍一下。


签名是什么大家都很熟悉吧?证明该东西是你写的,是你发布的,你就用签名搞定。看看那些重要文件都要头头签名。数字签名就是数字化的签名了。记得公用密钥和私有密钥的特征吗?只有你一个人有你自己的私有密钥。而你的公用密钥是其他人都知道的了。那么你在写完一封邮件之后,用自己的私有密钥加密自己的名字,接收人用你的公共密钥解开一看,哦,是你发的。这就是你的数字签名过程了。

上面的解释是很简化的了,其实数字签名比这个复杂多了,但我们没有了解的必要,知道数字签名是这么一回事就可以了。


还有一种我们需要知道的加密算法,其实我不觉得那是加密算法,应该叫哈希算法,英文是messagedigest,是用来把任何长度的一串明文以一定规则变成固定长度的一串字符串。它在SSL中的作用也很重要,以后会慢慢提及的。一般使用的是MD5,SHA.

base64不是加密算法,但也是SSL经常使用的一种算法,它是编码方式,用来把asc码和二进制码转来转去的。

具体的加密解密过程我们不需要了解,因为SSL根本不关心。但了解加密算法的一些基本原理是必要的,否则很难理解SSL。

对加密算法的细节有兴趣的同志,可以去网络上找这些加密算法的原理的文章和实现的程序来研究,不过先学数论吧。




标题:openssl简介--协议

发信站:BBS水木清华站(FriNov1020:30:492000)

引用请指明原作/译者fordesign@21cn.com



SSL(SecureSocketLayer)是netscape公司提出的主要用于web的安全通信标准,分为2.0版和3.0版.TLS(TransportLayerSecurity)是IETF的TLS工作组在SSL3.0基础之上提出的安全通信标准,目前版本是1.0,即RFC2246.SSL/TLS提供的安全机制可以保证应用层数据在互联网络传输不被监听,伪造和窜改.

一般情况下的网络协议应用中,数据在机器中经过简单的由上到下的几次包装,就进入网络,如果这些包被截获的话,那么可以很容易的根据网络协议得到里面的数据.由网络监听工具可以很容易的做到这一点。

SSL就是为了加密这些数据而产生的协议,可以这么理解,它是位与应用层和TCP/IP之间的一层,数据经过它流出的时候被加密,再往TCP/IP送,而数据从TCP/IP流入之后先进入它这一层被解密,同时它也能够验证网络连接俩端的身份。


它的主要功能就是俩个:
一:加密解密在网络中传输的数据包,同时保护这些数据不被修改,和伪造。
二:验证网络对话中双方的身份

SSL协议包含俩个子协议,一个是包协议,一个是握手协议。包协议是说明SSL的数据包应该如何封装的。握手协议则是说明通信双方如何协商共同决定使用什么算法以及算法使用的key。很明显包协议位于握手协议更下一层。我们暂时对包协议的内容没有兴趣。

SSL握手过程说简单点就是:通信双方通过不对称加密算法来协商好一个对称加密算法以及使用的key,然后用这个算法加密以后所有的数据完成应用层协议的数据交换。


握手一般都是由client发起的,SSL也不例外。

1client送给server它自己本身使用的ssl的version(ssl一共有三个version),加密算法的一些配置,和一些随机产生的数据,以及其他在SSL协议中需要用到的信息。

2server送给client它自己的SSL的version,加密算法的配置,随机产生的数据,还会用自己的私有密钥加密SERVER-HELLO信息。Server还同时把自己的证书文件给送过去。同时有个可选的项目,就是server可以要求需要客户的certificate。

3client就用server送过来的certificate来验证server的身份。如果server身份验证没通过,本次通信结束。通过证书验证之后,得到server的公共密钥,解开server送来的被其用私有密钥加密过的SERVER-HELLO信息,看看对头与否。如果不对,说明对方只有该server的公共密钥而没有私有密钥,必是假的。通信告吹。

4client使用到目前为止所有产生了的随机数据(sharedsecret),client产生本次握手中的premastersecret(这个步骤是有可能有server的参与的,由他们使用的加密算法决定),并且把这个用server的公共密钥加密,送回给server.如果server要求需要验证client,那么client也需要自己把自己的证书送过去,同时送一些自己签过名的数据过去。

SSL协议有俩种技术来产生sharedsecret(真不好意思,又是一个很难意译的词组),
一种是RSA,一种是EDH.

RSA就是我们上一章说过的一种不对称加密算法。首先server把自己的RSA公共密钥送给client,client于是用这个key加密一个随机产生的值(这个随机产生的值就是sharedsecret),再把结果送给server.

EDH也是一种不对称加密算法,但它与RSA不同的是,它好象没有自己固定的公共密钥和私有密钥,都是在程序跑起来的时候产生的,用完就K掉。其他的步骤俩者就差不多了。

RSA,DSA,DH三种不对称加密算法的区别也就在这里。RSA的密钥固定,后俩个需要一个参数来临时生成key.DH甚至要求双方使用同样的参数,这个参数要事先指定。如果SSL库没有load进这个参数,DH算法就没办法用。DSA没研究过。

5Server验证完client的身份之后,然后用自己的私有密钥解密得到premastersecret然后双方利用这个premastersecret来共同协商,得到mastersecret.

6双方用master一起产生真正的sessionkey,着就是他们在剩下的过程中的对称加密的key了。这个key还可以用来验证数据完整性。双方再交换结束信息。握手结束。

接下来双方就可以用协商好的算法和key来用对称加密算法继续下面的过程了。

很简单吧?其实要复杂一些的,我简化了很多来说。

不过还是有个问题,喜欢捣蛋的人虽然看不懂他们在交流些什么,但篡改总可以吧?
记得我们在加密算法里面介绍过的哈希算法吗?就是为了对付这种捣蛋者的。在每次送信息的时候,附带把整条信息的哈希值也送过去,接收方收到信息的时候,也把收到的内容哈希一把,然后和对方送来的哈希值对比一下,看看是否正确。捣蛋者如果乱改通信内容,哈希出来的值是不同的,那么就很容易被发现了。


但这样子,捣蛋者至少可以学舌。他可以把之前监听到的内容重复发给某一方,而这些内容肯定是正确的,无法验证出有问题的。哎,SSL是怎么对付这种人的我还没看出来。有篇文章说:多放点随机数在信息里可以对付,我也没去研究这句话是什么意思。




openssl简介-入门
实现了SSL的软件不多,但都蛮优秀的。首先,netscape自己提出来的概念,当然自己会实现一套了。netscape的技术蛮优秀的,不过我没用过他们的ssl-toolkit.甚至连名字都没搞清楚。
1995年,eric.young开始开发openssl,那时候叫ssleay.一直到现在,openssl还在不停的修改和新版本的发行之中。openssl真够大的,我真佩服eric的水平和兴趣。这些open/free的斗士的精神是我写这个系列的主要动力,虽然写的挺烦的。
ps:eric现在去了RSA公司做,做了一个叫SSL-C的toolkit,其实和openssl差不多。估计应该比openssl稳定,区别是这个是要银子的,而且几乎所有低层的函数都不提供直接调用了。那多没意思。
去www.openssl.orgdownopenssl吧,最新的是0.9.6版。
安装是很简单的。我一直用的是sunsparc的机器,所以用sunsparc的机器做例子。
gunzip-dopenssl.0.9.6.tar.gz
tar-xfopenssl.0.9.6.tar
mvopenssl.0.9.6openssl
cdopenssl
./configure--prefix=XXXXX--openssldir=XXXXXXXX
(这里prefix是你想安装openssl的地方,openssldir就是你tar开的openssl源码的地方。好象所有的出名点的freesoftware都是这个操行,configure,make,maketest,makeinstall,搞定。)
./make(如果机器慢,这一步的时候可以去洗个澡,换套衣服)
./maketest
./makeinstall
OK,如果路上没有什么问题的话,搞定。
经常有人报bug,在hp-ux,sgi上装openssl出问题,我没试过,没发言权。
现在可以开始玩openssl了。
注意:我估计openssl最开始是在linux下开发的。大家可以看一看在linxu下有这么一个文件:/dev/urandom,在sparc下没有。这个文件有什么用?你可以随时找它要一个随机数。在加密算法产生key的时候,我们需要一颗种子:seed。这个seed就是找/dev/urandom要的那个随机数。那么在sparc下,由于没有这么一个设备,很多openssl的函数会报错:"PRNGnotseeded".解决方法是:在你的~/.profile里面添加一个变量$RANDFILE,设置如下:
$RANDFILE=$HOME/.rnd
然后在$HOME下vi.rnd,随便往里面乱输入一些字符,起码俩行。
很多openssl的函数都会把这个文件当seed,除了opensslrsa,希望openssl尽快修改这个bug.
如果用openssl做toolkit编程,则有其他不太安全的解决方法。以后讲到openssl编程的章节会详细介绍。
先生成自己的私有密钥文件,比如叫server.key
opensslgenrsa-des3-outserver.key1024
genras表示生成RSA私有密钥文件,-des3表示用DES3加密该文件,1024是我们的key的长度。一般用512就可以了,784可用于商业行为了,1024可以用于军事用途了。
当然,这是基于现在的计算机的速度而言,可能没过几年1024是用于开发测试,2048用于一般用途了。
生成server.key的时候会要你输入一个密码,这个密钥用来保护你的server.key文件,这样即使人家偷走你的server.key文件,也打不开,拿不到你的私有密钥。
opensslrsa-noout-text-inserver.key
可以用来看看这个key文件里面到底有些什么东西(不过还是看不懂)
如果你觉得server.key的保护密码太麻烦想去掉的话:
opensslrsa-inserver.key-outserver.key.unsecure
不过不推荐这么做

下一步要得到证书了。得到证书之前我们要生成一个CertificateSigningRequest.
CA只对CSR进行处理。
opensslreq-new-keyserver.key-outserver.csr
生成CSR的时候屏幕上将有提示,依照其指示一步一步输入要求的信息即可.
生成的csr文件交给CA签名后形成服务端自己的证书.怎么交给CA签名?
自己去www.verisign.com慢慢看吧。

如果是自己玩下,那么自己来做CA吧。openssl有很简单的方法做CA.但一般只好在开发的时候或者自己玩的时候用,真的做出产品,还是使用正规的CA签发给你的证书吧
在你makeinstall之后,会发现有个misc的目录,进去,运行CA.sh-newca,他会找你要CA需要的一个CA自己的私有密钥密码文件。没有这个文件?按回车创建,输入密码来保护这个密码文件。之后会要你的一个公司信息来做CA.crt文件。最后在当前目录下多了一个./demoCA这样的目录../demoCA/private/cakey.pem就是CA的key文件啦,
./demoCA/cacert.pem就是CA的crt文件了。把自己创建出来的server.crt文件copy到misc目录下,mv成newreq.pem,然后执行CA.sh-sign,ok,
得到回来的证书我们命名为server.crt.

看看我们的证书里面有些什么吧
opensslx509-noout-text-inserver.crt
玩是玩过了,openssl的指令繁多,就象天上的星星。慢慢一个一个解释吧。


wingger 回复于:2005-01-10 23:32:33

openssl简介-指令verify
用法:

opensslverify【-CApathdirectory】【-CAfilefile】【-purposepurpose】【-untrustedfile】【-help】【-issuer_checks】【-verbose】【-】【certificates】

说明:

证书验证工具。


选项
-CApathdirectory
我们信任的CA的证书存放目录。这些证书的名称应该是这样的格式:
xxxxxxxx.0(xxxxxxxx代表证书的哈希值。参看x509指令的-hash)
你也可以在目录里touch一些这样格式文件名的文件,符号连接到真正的证书。
那么这个xxxxxxxx我怎么知道怎么得到?x509指令有说明。
其实这样子就可以了:
opensslx509-hash-inserver.crt

-CAfilefile
我们信任的CA的证书,里面可以有多个CA的证书。

-untrustedfile
我们不信任的CA的证书。

-purposepurpose
证书的用途。如果这个option没有设置,那么不会对证书的CA链进行验证。

现在这个option的参数有以下几个:
sslclinet
sslserver
nssslserver
smimesign
smimeencrypt
等下会详细解释的。

-help
打印帮助信息。

-verbose

打印出详细的操作信息。

-issuer_checks
打印出我们验证的证书的签发CA的证书的之间的联系。
要一次验证多个证书,把那些证书名都写在后面就好了。

验证操作解释:
S/MIME和本指令使用完全相同的函数进行验证。
我们进行的验证和真正的验证有个根本的区别:
在我们对整个证书链进行验证的时候,即使中途有问题,我们也会验证到最后,而真实的验证一旦有一个环节出问题,那么整个验证过程就告吹。
验证操作包括几个独立的步骤。
首先建立证书链,从我们目前的证书为基础,一直上溯到RootCA的证书.
如果中间有任何问题,比如找不到某个证书的颁发者的证书,那么这个步骤就挂。有任何一个证书是字签名的,就被认为是RootCA的证书。
寻找一个证书的颁发CA也包过几个步骤。在openssl0.9.5a之前的版本,如果一个证书的颁发者和另一个证书的拥有着相同,就认为后一个证书的拥有者就是前一个证书的签名CA.
openssl0.9.6及其以后的版本中,即使上一个条件成立,还要进行更多步骤的检验。包括验证系列号等。到底有哪几个我也没看明白。
得到CA的名称之后首先去看看是否是不信任的CA,如果不是,那么才去看看是否是信任的CA.尤其是RootCA,更是必须是在信任CA列表里面。
现在得到链条上所有CA的名称和证书了,下一步是去检查第一个证书的用途是否和签发时候批准的一样。其他的证书则必须都是作为CA证书而颁发的。
证书的用途在x509指令里会详细解释。
过了第二步,现在就是检查对RootCA的信任了。可能RootCA也是每个都负责不同领域的证书签发。缺省的认为任何一个RootCA都是对任何用途的证书有签发权。
最后一步,检查整条证书链的合法性。比如是否有任何一个证书过期了?签名是否是正确的?是否真的是由该证书的颁发者签名的?
任何一步出问题,所有该证书值得怀疑,否则,证书检验通过。

如果验证操作有问题了,那么打印出来的结果可能会让人有点模糊。
一般如果出问题的话,会有类似这样子的结果打印出来:
server.pem:/C=AU/ST=Queensland/O=CryptSoftPtyLtd/CN=TestCA(1024bit)
error24at1depthlookup:invalidCAcertificate
第一行说明哪个证书出问题,后面是其拥有者的名字,包括几个字段。
第二行说明错误号,验证出错在第几层的证书,以及错误描述。
下面是错误号及其描述的详细说明,注意,有的错误虽然有定义,
但真正使用的时候永远不会出现。用unused标志.
0X509_V_OK
验证操作没有问题
2X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
找不到该证书的颁发CA的证书。
3X509_V_ERR_UNABLE_TO_GET_CRL(unused)
找不到和该证书相关的CRL
4X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE
无法解开证书里的签名。
5X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE(unused)
无法解开CRLs的签名。
6X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY
无法得到证书里的公共密钥信息。
7X509_V_ERR_CERT_SIGNATURE_FAILURE
证书签名无效
8X509_V_ERR_CRL_SIGNATURE_FAILURE(unused)
证书相关的CRL签名无效
9X509_V_ERR_CERT_NOT_YET_VALID
证书还没有到有效开始时间
10X509_V_ERR_CRL_NOT_YET_VALID(unused)
与证书相关的CRL还没有到有效开始时间
11X509_V_ERR_CERT_HAS_EXPIRED
证书过期
12X509_V_ERR_CRL_HAS_EXPIRED(unused)
与证书相关的CRL过期
13X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
证书的notBefore字段格式不对,就是说那个时间是非法格式。
14X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD
证书的notAfter字段格式不对,就是说那个时间是非法格式。
15X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD(unused)
CRL的lastUpdate字段格式不对。
16X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD(unused)
CRL的nextUpdate字段格式不对
17X509_V_ERR_OUT_OF_MEM
操作时候内存不够。这和证书本身没有关系。
18X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
需要验证的第一个证书就是字签名证书,而且不在信任CA证书列表中。
19X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
可以建立证书链,但在本地找不到他们的根??

:selfsignedcertificateincertificatechain
thecertificatechaincouldbebuiltupusingtheuntrustedcertificates
buttherootcouldnotbefoundlocally.
20X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
有一个证书的签发CA的证书找不到。这说明可能是你的RootCA的证书列表不齐全。
21X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
证书链只有一个item,但又不是字签名的证书。
22X509_V_ERR_CERT_CHAIN_TOO_LONG(unused)
证书链太长。
23X509_V_ERR_CERT_REVOKED(unused)
证书已经被CA宣布收回。
24X509_V_ERR_INVALID_CA
某CA的证书无效。
25X509_V_ERR_PATH_LENGTH_EXCEEDED
参数basicConstraintspathlentgh超过规定长度
26X509_V_ERR_INVALID_PURPOSE
提供的证书不能用于请求的用途。
比如链条中某个证书应该是用来做CA证书的,但证书里面的该字段说明该证书不是用做CA证书的,就是这样子的情况。
27X509_V_ERR_CERT_UNTRUSTED
RootCA的证书如果用在请求的用途是不被信任的。
28X509_V_ERR_CERT_REJECTED
CA的证书根本不可以用做请求的用途。
29X509_V_ERR_SUBJECT_ISSUER_MISMATCH
证书颁发者名称和其CA拥有者名称不相同。-issuer_checks被set的时候可以检验出来。
30X509_V_ERR_AKID_SKID_MISMATCH
证书的密钥标志和其颁发CA为其指定的密钥标志不同.
31X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH
证书系列号与起颁发CA为其指定的系列号不同。
32X509_V_ERR_KEYUSAGE_NO_CERTSIGN
某CA的证书用途不包括为其他证书签名。
50X509_V_ERR_APPLICATION_VERIFICATION
应用程序验证出错。


wingger 回复于:2005-01-10 23:39:26

openssl简介-指令asn1parse

用法:opensslasn1parse[-informPEM|DER][-infilename][-outfilename]

[-noout][-offsetnumber][-lengthnumber][-i][-structurefilename]

[-strparseoffset]

用途:一个诊断工具,可以对ASN1结构的东东进行分析。

ASN1是什么?一个用来描述对象的标准。要解释的话,文章可以比解释openssl结构的文章更长。有兴趣的话自己去网络上找来看吧。

-informDER|PEM|TXT
输入的格式,DER是二进制格式,PEM是base64编码格式,TXT不用解释了吧

-infilename
输入文件的名称,缺省为标准输入。

-outfilename
输入文件的名称,输入一般都是DER数据。如果没这个项,就没有东西输入咯。该项一般都要和-strparse一起使用。

-noout
不要输出任何东西(不明白有什么用)

-offsetnumber
从文件的那里开始分析,看到offset就应该知道是什么意思了吧。

-lengthnumber
一共分析输入文件的长度的多少,缺省是一直分析到文件结束。

-i
根据输出的数据自动缩进。

-structurefilename
当你输入的文件包含有附加的对象标志符的时候,使用这个。
这种文件的格式在后面会介绍。

-strparseoffset
从由offset指定的偏移量开始分析ASN1对象。当你碰到一个嵌套的对象时,可以反复使用这个项来一直进到里面的结构捏出你需要的东东。
一般分析完之后输入的东东如下:
opensslasn1parse-outtemp.ans-i-informpem<server.crt

0:d=0hl=4l=881cons:SEQUENCE

4:d=1hl=4l=730cons:SEQUENCE

.......

172:d=3hl=2l=13prim:UTCTIME:000830074155Z

187:d=3hl=2l=13prim:UTCTIME:010830074155Z

202:d=2hl=3l=136cons:SEQUENCE

205:d=3hl=2l=11cons:SET

......

359:d=3hl=3l=141prim:BITSTRING

......
本例是一个自签名的证书。每一行的开始是对象在文件里的偏移量。d=xx是结构嵌套的深度。知道ASN1结构的人应该知道,每一个SET或者SEQUENCE都会让嵌套深度增加1.
hl=xx表示当前类型的header的长度。1=xx表示内容的八进制的长度。
-i可以让输出的东西容易懂一点。
如果没有ASN.1的知识,可以省略看这一章。
本例中359行就是证书里的公共密钥。可以用-strparse来看看
opensslasn1parse-outtemp.ans-i-informpem-strparse359<server.crt

0:d=0hl=3l=137cons:SEQUENCE

3:d=1hl=3l=129prim:INTEGER:C0D802B4C084B20569C619C0FDF

466EEB7980920A408D51DA22C20427AC32488665D931C41E3274912DE2F25C8CA9C97B75

415C01794B622DBEADD92DA068C140C3AD387BF5FDC9A8D2FCEE7F7F3E36B0194994FD67

07897C8969F16F6ECB3F03BF985E910817160FE5DCBF874B1C0DBD06A568E130DA7C9FE3

9FE7A7F421369

135:d=1hl=2l=3prim:INTEGER:010001
不要试图去看temp.ans的内容,是二进制来的,看不懂的。


wingger 回复于:2005-01-10 23:41:07

openssl简介-指令ca

用途:
模拟CA行为的工具.有了它,你就是一个CA,不过估计是nobodytrustedCA.可以用来给各种格式的CSR签名,用来产生和维护CRL(不记得CRL是什么了?去看证书那一章).他还维护着一个文本数据库,记录了所有经手颁发的证书及那些证书的状态。
用法:
opensslca[-verbose][-configfilename][-namesection][-gencrl]

[-revokefile][-crldaysdays][-crlhourshours][-crlextssection]

[-startdatedate][-enddatedate][-daysarg][-mdarg][-policyarg]

[-keyfilearg][-keyarg][-passinarg][-certfile][-infile]

[-outfile][-notext][-outdirdir][-infiles][-spkacfile]

[-ss_certfile][-preserveDN][-batch][-msie_hack][-extensionssection]

哇噻,好复杂也。不过用过GCC的人应该觉得这么点flag还是小case.

-configfilename
指定使用的configure文件。

-infilename
要签名的CSR文件。

-ss_certfilename
一个有自签名的证书,需要我们CA签名,就从这里输入文件名。

-spkacfilename
这一段实在没有看懂,也没兴趣,估计和SPKAC打交道可能性不大,奉送上英文原文。
afilecontainingasingleNetscapesignedpublickeyandchallengeandadditionalfieldvaluestobesignedbytheCA.
SPKACFORMAT
Theinputtothe-spkaccommandlineoptionisaNetscapesignedpublickeyandchallenge.ThiswillusuallycomefromtheKEYGENtaginanHTMLformtocreateanewprivatekey.ItishoweverpossibletocreateSPKACsusingthespkacutility.
ThefileshouldcontainthevariableSPKACsettothevalueoftheSPKACandalsotherequiredDNcomponentsasnamevaluepairs.Ifyouneedtoincludethesamecomponenttwicethenitcanbeprecededbyanumberanda.
-infiles
如果你一次要给几个CSR签名,就用这个来输入,但记得这个选项一定要放在最后。这个项后面的所有东东都被认为是CSR文件名参数。
-outfilename
签名后的证书文件名。证书的细节也会给写进去。
-outdirdirectory
摆证书文件的目录。证书名就是该证书的系列号,后缀是.pem
-cert
CA本身的证书文件名
-keyfilefilename
CA自己的私有密钥文件
-keypassword
CA的私有密钥文件的保护密码。
在有的系统上,可以用ps看到你输入的指令,所以这个参数要小心点用。
-passinarg
也是一个输入私有密钥保护文件的保护密码的一种方式,可以是文件名,设备名或者是有名管道。程序会把该文件的第一行作为密码读入。(也蛮危险的)。
-verbose
操作过程被详细printf出来
-notext
不要把证书文件的明文内容输出到文件中去。
-startdatedate
指明证书的有效开始日期。格式是YYMMDDHHMMSSZ,同ASN1的UTCTime结构相同。
-enddatedate
指明证书的有效截止日期,格式同上。
-daysarg
指明给证书的有效时间,比如365天。
-mdalg
签名用的哈希算法,比如MD2,MD5等。
-policyarg
指定CA使用的策略。其实很简单,就是决定在你填写信息生成CSR的时候,哪些信息是我们必须的,哪些不是。看看config文件里面的policy这个item就明白了。
-msie_hack
为了和及其古老的证书版本兼容而做出的牺牲品,估计没人会用的,不解释了。
-preserveDN
和-msie_hack差不多的一个选项。
-batch
设置为批处理的模式,所有的CSR会被自动处理。
-extensionssection
我们知道一般我们都用X509格式的证书,X509也有几个版本的。如果你在这个选项后面带的那个参数在config文件里有同样名称的key,那么就颁发X509V3证书,否则颁发X509v1证书。
还有几个关于CRL的选项,但我想一般很少人会去用。我自己也没兴趣去研究。
有兴趣的自己看看英文吧。

CRLOPTIONS

-gencrl

thisoptiongeneratesaCRLbasedoninformationintheindexfile.
-crldaysnum

thenumberofdaysbeforethenextCRLisdue.Thatisthedaysfrom

nowtoplaceintheCRLnextUpdatefield.

-crlhoursnum

thenumberofhoursbeforethenextCRLisdue.

-revokefilename

afilenamecontainingacertificatetorevoke.

-crlextssection

thesectionoftheconfigurationfilecontainingCRLextensionsto

include.IfnoCRLextensionsectionispresentthenaV1CRLiscreated,

iftheCRLextensionsectionispresent(evenifitisempty)thenaV2

CRLiscreated.TheCRLextensionsspecifiedareCRLextensionsandnot

CRLentryextensions.Itshouldbenotedthatsomesoftware(forexample

Netscape)can'thandleV2CRLs.

相信刚才大家都看到很多选项都和config文件有关,那么我们来解释一下config文件makeinstall之后,openssl会生成一个全是缺省值的config文件:openssl.cnf.也长的很,贴出来有赚篇幅之嫌,xgh不屑。简单解释一下其中与CA有关的key.
与CA有关的key都在ca这个section之中。
[ca]
default_ca=CA_default
[CA_default]
dir=./demoCA#Whereeverythingiskept
certs

本文地址:http://www.45fan.com/a/question/67173.html
Tags: 简介 前言 openssl
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部