一、SSL概述
SSL连接分为两个阶段:握手和数据传输阶段。握手阶段对服务器进行认证并确立用于保护数据传输的加密密钥,必须在传输任何应用数据之前完成握手。一旦握手完成,数据就被分成一系列经过保护的记录进行传输。

1.1.握手
SSL握手有三个目的:

客户端与服务器需要就一组用于保护数据的算法达成一致;
他们需要确立一组由那些算法所使用的加密密钥;
握手可以选择对客户端进行认证。
整个工作过程如下图:

(1)客户端将它支持的算法列表+用于密钥产生过程的随机数发送给服务器;
(2)服务器从列表中的内容选择一种加密算法,并将其连同一份包含服务器公用密钥的证书发回给客户端;(证书包含了用于认证目的的服务器标识,同时,服务器还提供了一个作为密钥产生过程部分输入的随机数)
(3)客户端对服务器的证书进行验证,并取出服务器的公用密钥(用于之后加密发给服务器的信息);然后产生一个称为pre_master_secret的随机密码串,并使用服务器的公用密钥对其进行加密。最后,客户端将加密后的信息发送给服务器;
(4)客户端与服务器根据pre_master_secret以及客户端与服务器的随机数独立计算出加密和MAC密钥;
(5)客户端将所有握手信息的MAC值发送给服务器;
(6)服务器将所有握手信息的MAC值发送给客户端。
通过上述过程,就已经达到了SSL握手三个目的中的前两个目的了。其中,第一步和第二步实现了第一个目标(确立一种加密算法);第二步和第三步实现了第二个目标,在第2步中,服务端向客户端提供服务器公用密钥的证书,这样就允许客户端给服务器传送密码。经过第三步后,两端都知道了pre_master_secret(客户端知道是因为这是它产生的,服务端知道是因为它利用私密密钥解密得到的)。第四步,两端采用相同的密钥导出函数(KDF)来产生master_secret,最后再次通过KDF使用master_secret来产生加密密钥。最后两步是防止握手本身遭到篡改。

对应着上一张图和这一张图,握手过程是通过一条或者多条消息实现的。

第 1 步对应一条单一的握手消息, ClientHello。
第 2 步对应一系列 SSL 握手消息,服务器发送的第一条件消息为 ServerHello,其中包含了它所选择的算法,接着再在 Certificate 消息中发送其证书。最后,服务器发送ServerHelloDone 消息以表示这一握手阶段的完成。需要 ServerHelloDone 的原因是一些更为复杂的握手变种还要在 Certificate 之后发送其他一些消息。 当客户端接收到 ServerHelloDone消息时,它就知道不会再有其他类似的消息过来了,于是就可以继续它这一方的握手。
第 3 步对应 ClientKeyExchange 消息。
第 5 与第 6 步对应 Finished 消息。 该消息是第一条使用刚刚磋商过的算法加以保护的消息。为了防止握手过程遭到篡改,该消息的内容是前一阶段所有握手消息的 MAC 值。然而,由于 Finished 消息是以磋商好的算法加以保护的,所以也要与新磋商的 MAC 密钥一起计算消息本身的 MAC 值。
二、SSL记录协议
在SSL中,实际的数据传输是使用SSL记录协议来实现的。SSL记录协议时通过将数据流分割成一系列的片段并加以传输来工作的,其中对每个片段单独进行保护和传输。在接收方对每条记录单独进行解密和验证。

在传输片段之前,通过计算数据的MAC来提供完整性保护。MAC与片段一起传输,并由接收实现加以验证。将MAC附加到片段的尾部,并对数据与MAC整合在一起的内容进行加密,以形成经过加密的负载。最后给负载装上头部信息。头信息与经过加密的负载的联结称为记录(Record),记录就是实际传输的内容。

2.1.记录头信息
记录头信息的工作就是为接收实现提供对记录进行解释所需的信息。在实际应用中是指三种信息:内容类型、长度和SSL版本。

长度字段:可让接收方知道它要从线路上读取多少直接才能对消息进行处理;
版本号:确保每一方使用所磋商的版本的冗余性检查;
内容类型:标识消息类型。
2.2.内容类型 
SSL支持四种内容类型:application_data、alert、handshake和change_cipher_spec。

application_data:使用SSL软件发送和接收的所有数据都是以application_data类型来发送的;
alert:主要用于报告各种类型的错误;
handshake:承载握手消息;
change_cipher_spec:标识记录加密以及认证的改变,一旦握手商定了一组新的密钥,就发送change_cipher_spec来指示此刻将启用新的密钥。
2.3.SSL规范语言
TLS和SSLv3都是使用同一种规范语言来描述他们各自的消息的。规范使用五种基本类型:opaque、uint8、uint16、uint24和uint32,分别对应无符号的8-、16-、24-和32-位整数,并在线路上以1、2、3或4字节序列加以表示。所有的数字都以“网络字节顺序”——高位在前来表示。

2.3.1.向量vector
向量是给定元素类型的元素序列,分为定长和变长向量。其中,定长向量用[]表示,变长向量用<>表示。长度以字节而不是元素个数为单位,所以uint16 foo[4]是表示是指两个16位整数,而不是4个!(长度为4字节,uint16位16位整数,即两字节整数,因此4个字节包含两个16位整数)。这样就允许解码器具有分层的结构,它可以将结构当做不透明的字符串(因为它知道它们的长度)来看待,并将其传送给另一层加以解析。

此外,可以通过长度的上限与下限、或只指定上限来表示变长向量。

// A string of between 1 and 20 bytes
opaque stuff<1..20>

// Up to 4 32 bit integers
uint32 numbers<16>
2.3.2.枚举类型
枚举类型就是假定只有一系列特定值的字段,且每个值都有名字。

enum{red(1),blue(2),green(3)}colors;
指定一个名为colors 的类型,他们可以接收值red、blue和green,在线路上用整数1、2和3来表示。当在线路上对枚举变量进行编码时,用一个大到足以容纳其最大值的整数类型来表示,因此用一个字节的uint8来表示colors。也可以通过显式包含一个未命名的值来为一个枚举变量显式指定最大尺寸:

enum{warning(1),fatal(2),(255)}AlertLevel;
2.3.3.结构
使用struct来构造结构化类型(与C语言类似):

struct{
type1 field1,
type2 field2,
type3 field3,
……
}name;
 2.3.4.变体类型
可以将结构定义成依赖外部信息而变化的变体(Variant)类型,使用一种表面上看起来类似于C语言中的switch语句的结构来进行定义(类似于C语言中的union):

select(type){
case value1:Type1
case value2:Type2
……
}name;
2.4.握手消息结构
头信息为4字节长,包括一个字节的类型字段和3个字节的长度字段组成,长度字段表示剩余握手消息的长度(不包括类型与长度字段),余下的消息内容完全有赖于msg_type字段。

struct{
HandshakeType msg_type;
uint24 length;
select(HandshakeType){
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
}body;
}Handshake;

enum{
hello_request(0),client_hello(1),server_hello(2),
certificate(11),server_key_exchange(12),certificate_request(13),
server_hello_done(14),certificate_verify(15),client_key_exchange(16),
finished(20),(255)
}HandshakeType;
 
---------------------
作者:冯Jungle
来源:CSDN
原文:https://blog.csdn.net/sinat_21107433/article/details/88366880
版权声明:本文为博主原创文章,转载请附上博文链接!

SSL连接分为两个阶段:握手和数据传输阶段的更多相关文章

  1. 使用 JSSE 定制 SSL 连接的属性--转载

    当数据在网络上传播的时候,通过使用 SSL 对其进行加密和保护,JSSE 为 Java 应用程序提供了安全的通信.在本篇有关该技术的高级研究中,Java 中间件开发人员 Ian Parkinson 深 ...

  2. 分布式事务、XA、两阶段提交、一阶段提交

    本文原文连接:http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的分布式事务的规范 ...

  3. 在libuv中使用openssl建立ssl连接

    在libuv中使用openssl建立ssl连接 @(blogs) 使用openssl进行加密通信时,通常是先建立socket连接,然后使用SSL_XXX系列函数在普通socket之上建立安全连接,然后 ...

  4. 配置oracle的ssl连接

    配置oracle的ssl连接   网上也没有中文资料,我硬着头皮看官方文档肯完,终于配置成功,下面是我配置步骤 配置安全套接层连接oracle 目录 1.        配置简介        1 2 ...

  5. TCP三次握手的过程,accept发生在三次握手的哪一个阶段?

    答案是:accept过程发生在三次握手之后,三次握手完成后,客户端和服务器就建立了tcp连接并可以进行数据交互了.这时可以调用accept函数获得此连接. TCP Accept总结 TCP Accep ...

  6. HTTPS详解二:SSL / TLS 工作原理和详细握手过程

    HTTPS 详解一:附带最精美详尽的 HTTPS 原理图 HTTPS详解二:SSL / TLS 工作原理和详细握手过程 在上篇文章HTTPS详解一中,我已经为大家介绍了 HTTPS 的详细原理和通信流 ...

  7. TCP3次握手连接协议和4次握手断开连接协议

    TCP/IP 状态机,如下图所示: 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图1所示. (SYN包表示标志位syn=1,ACK包表示标志位ack=1,SYN+A ...

  8. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究 转载

    1.XA XA是由X/Open组织提出的分布式事务的规范.XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接 ...

  9. 使用sslsplit嗅探tls/ssl连接

    首先发一个从youtube弄到的sslsplit的使用教程 http://v.qq.com/page/x/k/s/x019634j4ks.html 我最近演示了如何使用mitmproxty执行中间人攻 ...

随机推荐

  1. 用panels 制作drupal首页

    1.下载zen主题 路径:https://www.drupal.org/project/zen2.“启用并设为默认”3.基于zen制作子主题 把zen目录下STARTERKIT文件夹,复制到sites ...

  2. gSOAP 初体验

    安装 由于本人使用的是 Mac OS 系统,故以 Mac OS 为例说明如何安装 gSOAP. 1)下载 gSOAP 可以在 https://sourceforge.net/projects/gsoa ...

  3. 总结一下搭建简单Web服务器的一些方法

    使用nodejs+anywhere模块搭建静态文件服务器 anywhere随时随地将你的当前目录变成一个静态文件服务器的根目录. 安装npm install anywhere -g,然后进入任意目录在 ...

  4. 使用WPF Animated GIF实现GIF图片的播放

    这个类库很方便,也很简单:http://wpfanimatedgif.codeplex.com/ 参考博客:http://blog.csdn.net/gqqnb/article/details/721 ...

  5. SpringBoot Logback配置,SpringBoot日志配置

    SpringBoot Logback配置,SpringBoot日志配置  SpringBoot springProfile属性配置 ================================ © ...

  6. TransmittableThreadLocal 解决 线程池线程复用 无法复制 InheritableThreadLocal 的问题.

    ThreadLoacl,InheritableThreadLocal,原理,以及配合线程池使用的一些坑 TransmittableThreadLocal 原理 之前为了能让InheritableThr ...

  7. CentOS 6 添加root权限账户

    sudo adduser william sudo passwd william //两次输入密码 赋予root权限 visudo 找到 ## Allow root to run any comman ...

  8. IDEA导入springboot项目不能启动

    由于工具没有识别到项目的pom.xml文件,所以需要在右侧的Maven栏目中点击 + 号,选中项目的pom.xml文件,则导入成功.

  9. sublime3 配置go的开发环境

    配置go的环境变量:https://studygolang.com/articles/4910 配置sublime:https://studygolang.com/articles/4938

  10. 【Vue】---编写Vue插件流程---【巷子】

    一.在Vue中编写插件流程 1.创建组件 components/message.vue <template> <div class="message" v-if= ...