SSL的握手协议介绍
2015-11-27 13:53:58 阿炯

SSL-Secure Sockets Layer(安全套接字层)是以公钥基础结构为基础的网络安全解决方案。是由Netscape公司提出的一种建立在网络传输层TCP协议之上的安全协议标准工作在Socket网络通信层上,用来在客户端和服务器之间建立安全的TCP连接,向基于TCP/IP协议的客户/服务器应用程序提供客户端和服务器的验证、数据完整性及信息保密性等安全措施。SSL协议主要用于浏览器和WEB服务器之间建立安全的数据传输通道,还适用于Telnet、FTP和NNTP等服务。

1、SSL的工作机制:
1.客户端向服务器提出请求,要求建立安全通信连接。
2.客户端与服务器进行协商,确定用于保证安全通信的加密算法和强度。
3.服务器将其服务器证书发送给客户端。该证书包含服务器的公钥,并用CA的私钥加密。
4.客户端使用CA的公钥对服务器证书进行解密,获得服务器公钥。客户端产生用于创建会话密钥的信息,并用服务器公钥加密,然后发送到服务器。
5.服务器使用自己的私钥解密该消息,然后生成会话密钥,然后将其用服务器公钥加密,再发送给客户端。这样服务器和客户端双方就都拥有了会话密钥。
6.服务器和客户端使用会话密钥来加密和解密传输的数据。它们之间数据传输使用的是对称加密。

2、SSL协议主要解决3个关键问题
1.客户端对服务器的身份确认
2.服务器对客户的身份确认
3.在服务器和客户之间建立安全的数据通道

说明:对于SSL安全来说,客户认证是可选的,即不强制进行客户端验证。这有利于SSL的广泛使用,如果要强制客户端验证,就要求每个客户端都有自己的公钥,并且服务器要对每个客户端进行认证,仅为每个用户分发公钥和数字证书,对于客户基数大的应用来说负担很重。而在实际应用中,服务器的认证更为重要,因为确保用户知道自己正在和哪个服务器进行连接,比商家知道自己在和哪个用户进行连接更为重要。而且服务器比客户数量要少得多,为服务器配备公钥和站点证书易于实现。

SSL通信的特点:

1. 用户浏览器将其SSL版本号、加密设置参数、与session有关的数据以及其它一些必要信息发送到服务器。
2. 服务器将其SSL版本号、加密设置参数、与session有关的数据以及其它一些必要信息发送给浏览器,同时发给浏览器的还有服务器的证书。如果配置服务器的SSL需要验证用户身份,还要发出请求要求浏览器提供用户证书。
3. 客户端检查服务器证书,如果检查失败,提示不能建立SSL连接。如果成功,那么继续。
4. 客户端浏览器为本次会话生成pre-master secret,并将其用服务器公钥加密后发送给服务器。
5. 如果服务器要求鉴别客户身份,客户端还要再对另外一些数据签名后并将其与客户端证书一起发送给服务器。
6. 如果服务器要求鉴别客户身份,则检查签署客户证书的CA是否可信。如果不在信任列表中,结束本次会话。如果检查通过,服务器用自己的私钥解密收到的pre-master secret,并用它通过某些算法生成本次会话的master secret。
7. 客户端与服务器均使用此master secret生成本次会话的会话密钥(对称密钥)。在双方SSL握手结束后传递任何消息均使用此会话密钥。这样做的主要原因是对称加密比非对称加密的运算量低一个数量级以上,能够显著提高双方会话时的运算速度。
8. 客户端通知服务器此后发送的消息都使用这个会话密钥进行加密。并通知服务器客户端已经完成本次SSL握手。
9. 服务器通知客户端此后发送的消息都使用这个会话密钥进行加密。并通知客户端服务器已经完成本次SSL握手。
10. 本次握手过程结束,会话已经建立。双方使用同一个会话密钥分别对发送以及接受的信息进行加、解密。
 
1、SSL通讯示意图
SSL通讯示意图如下图所示:


2、SSL通讯说明
在该部分,将对图1所示的示意图进行说明。为了说明的方便,在本文中称客户端为B,服务器端为S。
STEP 1: B-->S发起对话,协商传送加密算法
你好,S!我想和你进行安全对话,我的对称加密算法有DES,RC5,我的密钥交换算法有RSA和DH,摘要算法有MD5和SHA。

STEP2: S-->B发送服务器数字证书
你好,B!那我们就使用DES-RSA-SHA这对组合进行通讯,为了证明我确实是S,现在发送我的数字证书给你,你可以验证我的身份。

STEP 3: B-->S传送本次对话的密钥
检查S的数字证书是否正确,通过CA机构颁发的证书验证了S证书的真实有效性后。生成了利用S的公钥加密的本次对话的密钥发送给S
S, 我已经确认了你的身份,现在将我们本次通讯中使用的对称加密算法的密钥发送给你。

STEP4: S-->B获取密钥
S用自己的私钥解密获取本次通讯的密钥。
B, 我已经获取了密钥。我们可以开始通信了。

STEP5: S<——>B进行通讯
说明:一般情况下,当B是保密信息的传递者时,B不需要数字证书验证自己身份的真实性,如电子银行的应用,客户需要将自己的账号和密码发送给银行,因此银行的服务器需要安装数字证书来表明自己身份的有效性。在某些B2B应用,服务器端也需要对客户端的身份进行验证,这时客户端也需要安装数字证书以保证通讯时服务器可以辨别出客户端的身份,验证过程类似于服务器身份的验证过程。此外需要说明的是,在一些电子商务的应用中,可能还会使用到电子签名,或者为了信息交换的更加安全,会增加电子签名和消息校验码MAC。
 
为了便于了解SSL,下面在简要介绍一下信息加密相关知识。使用密钥类型加密信息的加密算法可以分为以下几类:HASH 编码、对称加密和非对称加密三类。

HASH 编码是使用HASH算法从任意长度的消息中计算HASH值的一个过程,HASH值可以说是消息的指纹,因为对于任何不同的消息,几乎总有不同的HASH值。因此在SSL通讯过程中,可以对消息的HASH值进行加密,确保传递的消息在传输过程中没有被修改。

非对称加密或称之为公钥加密使用数学上相关的两个数值来对信息进行编码加密,其中一个数字称为公钥,另一个称为私钥。公钥加密的信息可以用私钥解密,私钥加密的信息可以用公钥解密。由于公钥可以大面积发放,因此公钥加密在SSL加密通信中应用于对密钥的加密或者进行数字签名。

对称加密和非对称加密相比的区别在于对称加密中,加密信息和解密信息使用同样的密钥,因此该密钥无法公开。但是其具有加密、解密快速的特点。

在SSL通讯中,首先采用非对称加密交换信息,使得服务器获得浏览器端提供的对称加密的密钥,然后利用该密钥进行通讯过程中信息的加密和解密。为了保证消息在传递过程中没有被篡改,可以加密HASH编码来确保信息的完整性。

SSL原理解密

RSA公钥加密在计算机产业中被广泛使用在认证和加密。可以从RSA Data Security Inc.获得的RSA公钥加密许可证。公钥加密是使用一对非对称的密码加密或解密的方法。每一对密码由公钥和私钥组成,公钥被广泛发布。私钥是隐密的,不公开。用公钥加密的数据只能够被私钥解密。反过来,使用私钥加密的数据只能用公钥解密,这个非对称的特性使得公钥密很有用。

使用公钥加密法认证
认证是一个身份认证的过程。在下列例子中包括甲和乙,公钥加密会非常轻松地校验身份。符号{数据} key意味着"数据"已经使用密码加密或解密。假如甲想校验乙的身份。乙有一对密码,一个是公开的,另一个是私有的。乙透露给甲他的公钥。甲产生一个随机信息发送给乙。甲-->乙:random-message

乙使用他的私钥加密消息,返回甲加密后的消息。 乙-->甲:{random-message}乙的私钥
甲收到这个消息然后使用乙的以前公开过的公钥解密。他比较解密后的消息与他原先发给乙的消息。如果它们完全一致,就会知道在与乙说话。任意一个中间人不会知道乙的私钥,也不能正确加密甲检查的随机消息。

除非你清楚知道你加密的消息。用私钥加密消息,然后发送给其他人不是一个好主意。因为加密值可能被用来对付你,需要注意的是:因为只有你才有私钥,所以只有你才能加密消息。所以,代替加密甲发来的原始消息,乙创建了一个信息段并且加密。信息段取自随机消息random-message并具有以下有用的特性:
1. 这个信息段难以还原。任何人即使伪装成乙,也不能从信息段中得到原始消息;
2. 假冒者将发现不同的消息计算出相同的信息段值;
3. 使用信息段,乙能够保护自己。他计算甲发出的随机信息段,并且加密结果,并发送加密信息段返回甲。甲能够计算出相同的信息段并且解密乙的消息认证乙。
这个技术仅仅描绘了数字签名。通过加密甲产生的随机消息,乙已经在甲产生的消息签名。因此我们的认证协议还需要一次加密。一些消息由乙产生:
甲-->乙:你好,你是乙么?
乙-->甲:甲,我是乙
{信息段[甲,我是乙] } 乙的私钥
当你使用这个协议,乙知道他发送给乙的消息,他不介意在上面签名。他先发送不加密的信息,"甲,我是乙。",然后发送信息段加密的消息版本。甲可以非常方便地校验乙就是乙,同时乙还没有在他不想要的信息上签名。

提交公钥
那么,乙怎样以可信的方式提交他的公钥呢?看看认证协议如下所示:
甲-->乙:你好
乙-->甲:嗨,我是乙,乙的公钥
 
这是网络上看到的ssl的原理
除非你清楚知道你加密的消息。用私钥加密消息,然后发送给其他人不是一个好主意。因为加密值可能被用来对付你,需要注意的是:因为只有你才有私钥,所以只有你才能加密消息。所以,代替加密甲发来的原始消息,乙创建了一个信息段并且加密。信息段取自随机消息random-message并具有以下有用的特性:
1. 这个信息段难以还原。任何人即使伪装成乙,也不能从信息段中得到原始消息;
2. 假冒者将发现不同的消息计算出相同的信息段值;
3. 使用信息段,乙能够保护自己。他计算甲发出的随机信息段,并且加密结果,并发送加密信息段返回甲。甲能够计算出相同的信息段并且解密乙的消息认证乙。用私钥加密消息,然后发送给其他人不是一个好主意。文中说乙创建了一个信息段并且加密。信息段取自随机消息random-message并具有以下有用的特性:
取甲的消息的片段签名,这里是基于怎样一种机制?
 
换一种方式问问题
这个技术仅仅描绘了数字签名。通过加密甲产生的随机消息,乙已经在甲产生的消息签名。因此我们的认证协议还需要一次加密。一些消息由乙产生:
甲-->乙:你好,你是乙么?
乙-->甲:甲,我是乙
{信息段[甲,我是乙] } 乙的私钥
乙 不愿意对"你好,你是乙么? "这句话签名,乙用乙的私钥 签的是
"信息段[甲,我是乙]",这是一个什么东西?是信息段&[甲,我是乙] 还是其他什么?
 
建立ssl连接的简单过程是:客户端发一个握手消息,服务器发送自己的证书证明自己的身份证书中包含了自己的公钥),客户端获得证书后,创建一个密钥对乘密钥,并且封装到一个数字信封中,发送到服务器端,服务器是用自己的私钥解密数字信封,取出其中的密钥,这样双方都有了共同的密钥,可以使用这个密钥密密的通信。在ssl建立的过程中,服务器还可以要求客户端提交证书,证明客户端的身份,这样就是双向认证了。这种认证很难破解。

公钥, 私钥和SSL

一、公钥私钥
1,公钥和私钥成对出现
2,公开的密钥叫公钥,只有自己知道的叫私钥
3,用公钥加密的数据只有对应的私钥可以解密
4,用私钥加密的数据只有对应的公钥可以解密
5,如果可以用公钥解密,则必然是对应的私钥加的密
6,如果可以用私钥解密,则必然是对应的公钥加的密

明白了?假设一下,我找了两个数字,一个是1,一个是2。我喜欢2这个数字,就保留起来,不告诉你们,然后我告诉大家,1是我的公钥。

我有一个文件,不能让别人看,我就用1加密了。别人找到了这个文件,但是他不知道2就是解密的私钥啊,所以他解不开,只有我可以用数字2,就是我的私钥,来解密。这样我就可以保护数据了。

我的好朋友x用我的公钥1加密了字符a,加密后成了b,放在网上。别人偷到了这个文件,但是别人解不开,因为别人不知道2就是我的私钥,只有我才能解密,解密后就得到a。这样,我们就可以传送加密的数据了。

现在我们知道用公钥加密,然后用私钥来解密,就可以解决安全传输的问题了。如果我用私钥加密一段数据当然只有我可以用私钥加密,因为只有我知道2是我的私钥,结果所有的人都看到我的内容了,因为他们都知道我的公钥是1,那么这种加密有什么用处呢?

但是我的好朋友x说有人冒充我给他发信。怎么办呢?我把我要发的信,内容是c,用我的私钥2,加密,加密后的内容是d,发给x,再告诉他解密看是不是c。他用我的公钥1解密,发现果然是c。这个时候,他会想到,能够用我的公钥解密的数据,必然是用我的私钥加的密。只有我知道我得私钥,因此他就可以确认确实是我发的东西。这样我们就能确认发送方身份了。这个过程叫做数字签名。当然具体的过程要稍微复杂一些。用私钥来加密数据,用途就是数字签名。好,我们复习一下:
1,公钥私钥成对出现
2,私钥只有我知道
3,大家可以用我的公钥给我发加密的信了
4,大家用我的公钥解密信的内容,看看能不能解开,能解开,说明是经过我的私钥加密了,就可以确认确实是我发的了。

总结一下结论:
1,用公钥加密数据,用私钥来解密数据
2,用私钥加密数据数字签名,用公钥来验证数字签名。
在实际的使用中,公钥不会单独出现,总是以数字证书的方式出现,这样是为了公钥的安全性和有效性。


二、SSL
好朋友x,找了一个数字3,用我的公钥1,加密后发给我,说我们以后就用这个数字来加密信息吧。我解开后,得到了数字3。这样只有我们两个人知道这个秘密的数字3,别的人都不知道,因为他们既不知x挑了一个什么数字,加密后的内容他们也无法解开,我们把这个秘密的数字叫做会话密钥。然后,我们选择一种对称密钥算法,比如DES,对称算法是说,加密过程和解密过程是对称的,用一个密钥加密,可以用同一个密钥解密。使用公私钥的算法是非对称加密算法,来加密我们之间的通信内容。别人因为不知道3是我们的会话密钥,因而无法解密。好,复习一下:
1,SSL实现安全的通信
2,通信双方使用一方或者双方的公钥来传递和约定会话密钥 这个过程叫做握手
3,双方使用会话密钥,来加密双方的通信内容

上面说的是原理。大家可能觉得比较复杂了,实际使用中,比这还要复杂。不过庆幸的是,好心的先行者们在操作系统或者相关的软件中实现了这层Layer,并且起了一个难听的名字叫做SSL,Secure Socket Layer。

OpenSSL生成正确显示中文证书的方法

最近要用openssl生成证书,来配合https一起使用,可是没有根证书的签名,只能自签名一下,当用户访问https时会有一个安全警告,查看证书都是一堆字母和数字,里面如果能显示一些中文提示信息,就能让用户明白一些,这样可以少些问题。

openssl的req子命令创建的证书请求只能使用ASCII和UTF-8两种编码。

一开始创建的证书总是乱码,网上只找到了一篇文章是说如何创建中文证书的解决办法,其中还要修改openssl源代码,仔细看了他的修改方法,这是把所有的ASCII都作为UTF-8来处理了,因为主要修改的是:
switch(inform)的case MBSTRING_ASC
switch(outform)的case MBSTRING_ASC
部分的代码。

感觉他改的不对,就没有用他的办法改这部分代码,我就看了case MBSTRING_UTF8部分的代码,主要有两个函数比较重要,都在文件a_utf8.c中
switch(inform)时的UTF8_getc函数
switch(outform)时的UTF8_putc函数

里面的位操作很多,因一直对unicode的东西不熟悉,又看了UTF-8的资料,这里摘录一下UTF-8的重要特性:

* UCS 字符 U+0000 到 U+007F (ASCII) 被编码为字节 0x00 到 0x7F (ASCII 兼容). 这意味着只包含 7 位 ASCII 字符的文件在 ASCII 和 UTF-8 两种编码方式下是一样的.
* 所有 >U+007F 的 UCS 字符被编码为一个多个字节的串, 每个字节都有标记位集. 因此, ASCII 字节 (0x00-0x7F) 不可能作为任何其他字符的一部分.
* 表示非 ASCII 字符的多字节串的第一个字节总是在 0xC0 到 0xFD 的范围里, 并指出这个字符包含多少个字节. 多字节串的其余字节都在 0x80 到 0xBF 范围里. 这使得重新同步非常容易, 并使编码无国界, 且很少受丢失字节的影响.
* 可以编入所有可能的 231个 UCS 代码
* UTF-8 编码字符理论上可以最多到 6 个字节长, 然而 16 位 BMP 字符最多只用到 3 字节长.
* Bigendian UCS-4 字节串的排列顺序是预定的.
* 字节 0xFE 和 0xFF 在 UTF-8 编码中从未用到.

强烈建议配合这些特性看这两个函数UTF8_getc、UTF8_putc,会很有收获的,能充分理解UTF-8。可以肯定是,openssl中已完全实现了UTF-8的功能,可以制作中文证书。

经过各种试验终于可以在证书中使用UTF-8正确显示中文了,方法如下:
一、假设配置文件为openssl.cnf在openssl-0.9.8.d/apps/目录下,编辑修改如下内容:
string_mask = utf8only
countryName_default = CN
stateOrProvinceName_default = 中文的省份名称
localityName_default = 中文的城市名称
0.organizationName_default = 组织、公司
organizationalUnitName_default = 组织机构
commonName_default = 我的中文证书

二、用如下命令转换文件格式为UTF-8
iconv -f gbk -t utf-8 openssl.cnf > openssl_utf8.cnf
三、用openssl生成证书签名请求时,加上-utf8和将配置文件指定为openssl_utf8.cnf
openssl req -utf8 -config openssl_utf8.cnf -new -out server.req
除了输入密码,其他的一律enter,就OK了

然后将证书签名请求签名一下就生成有中文的证书了。
openssl x509 -in server.req -out server.crt -signkey privkey.pem -days 365

好了,安装一下server.crt,可以看看其中的中文信息。