SSL握手流程

一、SSL是什么?

安全套接字(SSL)协议是Web浏览器和Web服务器之间安全交换信息的协议。

SSL介于应用层和TCP层之间,应用层数据不再直接传递给传输层,而是传递给SSL层,SSL层对从应用层收到的数据进行加密,并增加自己的SSL头。

History:
1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。
1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。
1996年,SSL 3.0版问世,得到大规模应用。
1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。
2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。最新的变动是2011年TLS 1.2的修订版。

0x1:SSL记录协议:
1) 分组、组合
2) 压缩、解压缩
3) 以及消息认证
4) 加密传输等

0x2:SSL握手协议:
1). 客户机认证服务器
2). 协商客户机与服务器选择双方都支持的密码算法
3). 可选择的服务器认证客户
4). 使用公钥加密技术生成共享密钥
5). 建立加密SSL连接(过程都是明文的,握手完成之后才开始加密数据。)
0x3:SSL告警协议:SSL告警协议报文由严重级别和警告代码两部分组成

1. 严重级别(AlertLevel )
    1) Fatal
    Fatal级报警即致命级报警,它要求通信双方都要采取紧急措施,并终止会话,同时消除自己缓冲区相应的会话记录
    2) Waming
    Warning级报警即警告级报警的处理,通常是通信双方都只进行日志记录,它对通信过程不造成影响
2. 警告代码
    1) bad_record_mac:收到了不正确的MAC
  2) unexpected_message:接收了不合适的报文
    3) decompression_failure:解压缩函数收到不适当的输入。
    4) illegal_parameter:握手报文中的一个字段超出范围或与其他字段不兼容。
    5) certificate_revoked:证书已经被废弃。
    6) bad_certificate:收到的证书是错误的。
    7) certificate_expired:证书已经过期。
    8) handshake_failer:握手过程失败。
    9) no_certificate: 未提供证书
    10) unsupported_certificate: 未支持的证书格式
    11) certificate_unknown: 未知证书

二、SSL有什么用?

1. 秘密性: SSL客户机和服务器之间传送的数据都经过了加密处理,网络中的非法窃听者所获取的信息都将是无意义的密文信息

2. 完整性: SSL利用密码算法和散列(HASH)函数,通过对传输信息特征值的提取来保证信息的完整性,确保要传输的信息全部到达目的地,可以避免服务器和客户机之间的信息受到破坏。

3. 认证性:利用证书技术和可信的第三方认证,可以让客户机和服务器相互识别对方的身份。为了验证证书持有者是其合法用户(而不是冒名用户),SSL要求证书持有者在握手时相互交换数字证
书,通过验证来保证对方身份的合法性。

三、SSL和TLS的差异:

1. 版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0使用的版本号为SSLv3.1。
2. 报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。
3. 伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。
4. 报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如
    1) 解密失败(decryption_failed)
    2) 记录溢出(record_overflow)
    3) 未知CA(unknown_ca)
    4) 拒绝访问(access_denied)等。
5. 密文族和客户证书:SSLv3.0和TLS存在少量差别,即TLS"不支持":
    1) Fortezza密钥交换
    2) 加密算法
    3) 客户证书。
6. certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息计算MD5和SHA-1散列码时,计算的输入有少许差别,但安全性相当。
7. 加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。但都是以客户端和服务端各自产生的随机数Ramdom作为输入
8. 填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。

四、SSL过程

0x1: 流程  前两部称为“握手阶段”

1)客户端向服务器端索要并验证公钥
2)双方协商生成“对话密钥”(不用通信方的公钥进行加密<耗时>,只用对方的公钥来加密本端生成的“密钥”)
3)双方采用“对话密钥”进行加密通信。

0x2:具体过程  只关注单向认证

1. Client Hello:首先,客户端(浏览器)先向服务器发出加密通信请求,这被叫做ClientHello请求。

1) 支持的协议版本,比如TLS 1.0版。
2) 一个客户端生成的随机数A,稍后用于生成"对话密钥"。
3) 加密方法:支持的多种非对称加密方法、多种对称加密方法、多种MAC算法
4)  支持的压缩方法。

2.Server Hello:

1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
2) 一个服务器生成的随机数B,稍后用于生成"对话密钥"。
3) 确认使用的加密方法:从客户端提供的选出一个集合出来:{对称加密算法,非对称加密算法,MAC校验算法}

3. Certificate: server将“携带自己公钥信息的数字证书”和到根CA整个链通过Certificate消息发送给SSL客户端(整个公钥文件都发送过去)

1)客户端可以使用该公钥来验证服务器的身份

证书中的消息包括:

一般情况下客户端收到的是一个证书链,第一个是服务器的证书,之后是服务器证书签发者,最后是自签名的根证书。如下图,在实际解析中先要验证根CA的证书,然后是直接证书签发者证书,最后是服务器终端证书。

证书合法性的判断方法:

~颁布者的合法性(hash值)
~有效期
~签名值是否合法:首先对证书中除签名值部分的内容按照证书中的签名算法进行签名,把得到的签名按照asn.1编码方式进行编码:OBJECT格式的签名算法+ ASN_OCTET_STRING格式的签名值A;把证书中的签名值按照证书中的主体公钥算法进行解密得到B;当A和B完全相同时认为证书有效(证书制作过程中的签名值计算方法:计算得到A,和客户端计算方法相同,用服务器私钥对A进行加密,得到证书中的签名值)

2)公钥加密pre-naster secret (Client Key Exchange)

假设上面的证书验证通过了,这就意味着client相信server发过来的证书了,也就意味着client同意用server发过来的public key开始通讯了。注意,非对称加密的过程在这里开始了。client生成了一个pre-master secret(通常也是一个随机数)P,使用server提供的public key加密P之后生成P‘,将P‘发给了server。

server收到P‘后,用自己的private key解密还原出了P。注意这个P和之前A的最大不同是加密传输过来的哦。而且理论上在server没有泄露自己private key的情况下, 只有server能够从P‘还原出P。So,此时,client和server双方已经具备了生成双方后面通讯时对称加密需要使用的master secret的条件:双方都有的一个确定的伪随机函数、3个彼此都知道的随机数A、B和P。于是,双方在自己一方,通过共同的伪随机数和共同的素材,生成出来了master secret。

--------------

为什么要使用三个随机数?

1)"不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
2)对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。
3)pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret 作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是 是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的 可不是一。"

4. Change cipher Spec:通信双方协商好了对称加密的密钥和对称加密的算法之后,用这个消息进行测试

1)client用双方同意的MAC(message authentication code)算法,比如MD5加密一段明文Q,生成MAC,然后用双方都同意的对称加密算法(比如AES)加密Q和MAC之后,  生成一段Change Cipher Spec(content type:20).
2)Server收到这条TLS record之后,会先尝试解密密文,再用约定的MAC算法验证内容是否被篡改。这个如果这两个任何一项工作失败了,就前功尽弃了。这里假设都成功了,  于是server做了上一步client同样的事情:生成一份content type为20的Change cipher Spec发给client,至此,整个握手过程正式结束。

5. 下面的通讯就是双方直接使用对称加密算法直接加解密message的过程了,每次交互过程中,还会包括上面描述的MAC验证的过程。

参考资料:大部分资料来自网络,我只是稍加整理。风格是抄袭Little Hann大神的~勿喷

http://www.cnblogs.com/LittleHann/p/3733469.html
http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html
http://www.2cto.com/Article/201404/291859.html
http://blog.csdn.net/sealyao/article/details/5901510
时间: 2024-10-03 18:14:02

SSL握手流程的相关文章

i.BIO方式的SSL通道流程

前面已经讲解了BIO通道的整体流程,对于SSL的流程是插在通道中的,在BIO通道的初始化的时候,根据Connector配置的SSLEnabled属性进行SSL的逻辑. 主要集中的位置在JIOEndpoint的bind方法中: ' 这个特殊的ServerSocketFactory是SSLServerSocketFactory,我们看看其工厂创建之前做了什么内容,具体分解一下上述的这一行的代码: 左侧是Tomcat的类,Tomcat类中有两套SSL的实现,一套就是JSSEImplement,也就是基

OkHttp还处理了代理服务器问题和SSL握手失败问题

Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient,HttpURLConnection相对来说比HttpClient难用,google自从2.3版本之后一直推荐使用HttpURLConnection,并且在6.0版本的sdk中直接删掉了HttpClient类. 但是, 上面两个类库和OkHttp比起来就弱爆了, 因为OkHttp不仅具有高效的请求效率,并且节省宽带, 还提供了很多开箱即用的网络疑难杂症解决方案.(据说Android4.4的源码中可

SSL握手过程

一.SSL握手有三个目的:1. 客户端与服务器需要就一组用于保护数据的算法达成一致:2. 它们需要确立一组由那些算法所使用的加密密钥:3. 握手还可以选择对客户端进行认证. 二.SSL握手过程:1. 客户端将它所支持的算法列表和一个用作产生密钥的随机数发送给服务器:2. 服务器从算法列表中选择一种加密算法,并将它和一份包含服务器公用密钥的证书发送给客户端:该证书还包含了用于认证目的的服务器标识,服务器同时还提供了一个用作产生密钥的随机数:3. 客户端对服务器的证书进行验证(有关验证证书,可以参考

无效session ticket导致的SSL握手协商失败

SSL session ticket记录了加密参数,用于后续请求,减少握手次数,降低反复握手请求导致的高延迟. 如上截图,在SSL 握手完成之后,服务器生成session ticket.请求关闭后,如果客户端发起后续连接(超时时间内),可以随client hello复用这个session ticket,可以加快协商速度,如下截图:

CentOS6.5环境下OpenSSL实战:自己搭建CA中心,申请,签发,吊销,导入证书,SSL 握手详解

CentOS6.5环境下OpenSSL实战: 自己搭建CA中心,申请,签发,吊销,导入证书,SSL 握手详解

SSL握手

一.SSL握手有三个目的:1. 客户端与服务器需要就一组用于保护数据的算法达成一致:2. 它们需要确立一组由那些算法所使用的加密密钥:3. 握手还可以选择对客户端进行认证. 二.SSL握手过程:1. 客户端将它所支持的算法列表和一个用作产生密钥的随机数发送给服务器:2. 服务器从算法列表中选择一种加密算法,并将它和一份包含服务器公用密钥的证书发送给客户端:该证书还包含了用于认证目的的服务器标识,服务器同时还提供了一个用作产生密钥的随机数:3. 客户端对服务器的证书进行验证(有关验证证书,可以参考

捉虫记:QT5.2 SSL握手失败问题

最近在测试项目的时候,出现了这样一个bug:在某些win7和 win8主机上,我们的客户端使用paypal进行付款时,出现SSL握手失败的问题. 项目使用QT5.2.1开发,由于QT移植了开源的webkit,我们在项目中内置了一个浏览器,用来完成商品浏览和付款. 问题来了,当然需要进行"捉虫"了. 自从上次OpenSSL爆出"心脏出血"(见wiki),我们也使用了最新的openssl代码. 首先,需要定位问题出现的位置具体在哪里. 好在QT是开源的,方便我们定位问题

ssl握手协议中的CipherSuite

下面是一个ssl握手的过程,没有进行客户端验证: 1.C-S:ClientHello---cipher-suit-list 2.S-C:ServerHello---selected-cipher-suit 3.S-C:ServerKeyExchange 4.S-C:ServerHelloDone 5.C-S:ClientKeyExchange 6.C-S:完成 7.S-C:完成 第3步是否发送要看c和s协商的cipher-suit是什么,cipher-suit包含四个部分(将摘要算法并入认证算法

ssl握手数据结构

ssl握手 SSL记录头(5字节) 字节0:记录内容的类型 Content Type Hex Code Description Change_Cipher_Spec 0x14 指示加密方式的更改 Alert 0x15 发出各种类型的错误信号 Handshake 0x16 携带握手消息的记录 Application_Data 0x17 加密的应用数据 字节1和2:SSL版本(TLSv1是0x0301,SSLv3是0x0300) 字节3和4:记录长度(不包括前面5字节) 握手消息头(3字节) 字节0