HTTPS详解:SSL/TLS协议

摘要: 最近在看关于web安全相关的书籍,说到web安全HTTP和HTTPS之间的联系和区别是一个无法回避的问题。很长时间以来,我也被这个问题所困扰,对于其中涉及的细节问题更是难以触及,但是现在是该去好好考虑这个问题了。在网上查阅了大量资料之后,我发现很多文章在解释这个问题的时候含糊不清,让人难以理解。所以我写下了这篇博客,希望能给大家提供帮助,如有不足之处,欢迎指正!
avatar

文章概览

区别与联系

HTTP和HTTPS


联系


  HTTP(超文本传输协议)是一个客户端终端(用户)和服务器端(网站)请求和应答的标准(TCP)。通过使用网页浏览器、网络爬虫或者其它的工具,客户端发起一个HTTP请求到服务器上指定端口(默认端口为80)。我们称这个客户端为用户代理程序(user agent)。应答的服务器上存储着一些资源,比如HTML文件和图像。我们称这个应答服务器为源服务器(origin server)。在用户代理和源服务器中间可能存在多个“中间层”,比如代理服务器、网关或者隧道(tunnel)。可以从HTTP头、HTTP请求方法、HTTP状态码和统一资源定位符URL四个方面深入理解HTTP协议。
avatar
  超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,易遭受窃听、篡改、劫持等攻击,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密,一次HTTPS协议实现了数据传输过程中的保密性、完整性和身份认证性。

区别


  HTTP和HTTPS的主要区别如下包括:HTTPS协议需要到CA申请证书,而HTTP协议则不用;HTTP是超文本传输协议,信息是明文传输,而HTTPS则是加密传输;HTTP和HTTPS使用完全不同的连接方式,所占用的端口也不一样,前者占用80端口,后者占用443端口;HTTPS传输过程比较复杂,对服务端占用的资源比较多,由于握手过程的复杂性和加密传输的特性导致HTTPS传输的效率比较低;HTTP的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。

SSL和TLS

联系


  SSL(Secure Sockets Layer 安全套接层)为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取及窃听。SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
  安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面,与具体的应用无关,所以,一般把TLS协议归为传输层安全协议。TLS 的最大优势就在于:TLS 是独立于应用协议。高层协议可以透明地分布在 TLS 协议上面。然而,TLS 标准并没有规定应用程序如何在 TLS 上增加安全性;它把如何启动 TLS 握手协议以及如何解释交换的认证证书的决定权留给协议的设计者和实施者来判断。
  SSL是Netscape开发的专门用户保护Web通讯的,而TLS1.0是IETF(工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。两者差别很小,可以理解为SSL 3.1,它是写入了RFC的。为了兼顾各种说法本文将SSL和TLS统称为SSL/TLS,但是请注意,本文所涉及的关于各种协议的解析是基于TLS1.2版本(这是目前使用最广泛的版本)。

区别


  SSL和TLS的主要区别如下:

  • 版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同。
  • 报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。
  • 伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。
  • 报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如解密失败、记录溢出、未知、拒绝访问等。
  • 加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。
  • 填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。

SSL/TLS协议

密码套件(cipher suite)


  密码套件(Cipher suite)是传输层安全(TLS)/安全套接字层(SSL)网络协议中的一个概念。在TLS 1.2中,密码套件的名称是以协商安全设置时使用的身份验证、加密、消息认证码(MAC)和密钥交换算法组成。TLS 1.3中的密码套件格式已经修改。在目前的TLS 1.3草案文档中,密码套件仅用于协商加密和HMAC算法。在创建一个TLS连接后,一次也称TLS握手协议的握手发生。在这个握手,一条ClientHello和一条ServerHello消息被发出。首先,客户端按照偏好的顺序发送它支持的密码套件的列表。然后服务器回复它从客户端的列表中选择的密码套件。
  例如TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,每个密码套件名称定义一个密钥交换算法、一个批量加密算法、一个消息认证码(MAC)算法,以及一个伪随机函数(PRF)

  • 密钥交换算法,例如ECDHE_RSA,用于决定客户端与服务器之间在握手时如何身份验证
  • 批量加密算法,例如AES_128_GCM,用于加密消息流。它还包括密钥大小及显式和隐式初始化向量(密码学随机数)的长度
  • 消息认证码算法,例如SHA256,用于创建消息摘要,消息流每个数据块的加密散列
  • 伪随机函数,例如TLS 1.2的伪随机函数使用MAC算法的散列函数来创建一个主密钥——连接双方共享的一个48字节的私钥。主密钥在创建会话密钥(例如创建MAC)时作为一个熵来源

理解密码套件的作用以及组成部分对我们理解握手协议的过程十分重要,因为使用不同的密码套件在握手协议的实现细节上有很大的不同,特别是密钥交换的过程。本文将主要讲解ECDHE_RSA密钥交换算法下的握手过程(也可以理解为三种不同密码套件的握手过程,对于握手过程而言不同套件的差异主要体现在密钥交换的过程,批量加密算法和消息验证码算法的不同主要体现在加密传输的过程,伪随机算法的不同体现在产生分组加密初始向量的过程)。

记录协议


  TLS记录协议位于TLS握手协议的下层,在可靠的传输协议(如TCP/IP)上层。TLS记录协议的一条记录包含长度字段、描述字段和内容字段。TLS记录协议处理数据的加密,即记录协议得到要发送的消息之后,将数据分成易于处理的数据分组,进行数据压缩处理(可选),计算数据分组的消息认证码MAC,加密数据然后发送数据;接收到的消息首先被解密,然后校验MAC值,解压缩,重组,最后传递给协议的高层客户。记录协议有四种类型的客户:握手协议、警告协议、改变密码格式协议和应用数据协议。通常使用一个对称算法,算法的密钥由握手协议提供的值生成。TLS 记录协议提供的连接安全性具有两个基本特性:

  • 私有――对称加密用以数据加密(DES 、RC4 等)。对称加密所产生的密钥对每个连接都是唯一的,且此密钥基于另一个协议(如握手协议)协商。记录协议也可以不加密使用
  • 可靠――信息传输包括使用密钥的 MAC 进行信息完整性检查。安全哈希功能( SHA、MD5 等)用于 MAC 计算。记录协议在没有 MAC 的情况下也能操作,但一般只能用于这种模式,即有另一个协议正在使用记录协议传输协商安全参数

握手协议


  TLS握手协议处理对等用户的认证,在这一层使用了公共密钥和证书,并协商算法和加密实际数据传输的密钥,该过程在TLS记录协议之上进行。TLS握手协议是TLS协议中最复杂的部分,它定义了10种消息,客户端和服务器利用这10种消息相互认证,协商哈希函数和加密算法并相互提供产生加密密钥的机密数据。TLS记录协议会在加密算法中用到这些加密密钥,从而提供数据保密性和一致性保护。
  我们先来分析基于ECDHE_RSA密钥交换算法的握手过程,在这之前先来解释一下ECDHE是什么。ECDHE_RSA = EC(椭圆曲线加密算法)+ DH(Diffie-Hellman密钥交换算法)+ E(临时的temporary)+ RSA(用于签名,防止中间人攻击),所以ECDHE的意思是结合椭圆曲线的生成临时会话密钥的密钥交换算法。对于这个算法的具体计算过程,这里不详细讨论。
  下图是EDCHE_RSA密钥交换算法的大致流程,接下来我会结合wireshark抓取的数据包来分析握手的过程:
avatar

  • 在客户端和服务器开始握手之前先进行TCP三次握手,这部分的内容本文不会讨论。三次握手之后,开始握手协议,先在这展示一下抓到的所有握手包。

    avatar

  • Client hello:由于客户端对一些加解密算法的支持程度不一样,但是SSL/TLS协议传输过程中必须要求客户端与服务器端使用相同的加解密算法。所以在client hello阶段,客户端要首先告知服务端,自己支持哪些密码套件,客户端将支持的密码套件列表发送给服务端;同时客户端还会产生一个随机数,这个随机数双方都要保存(生成主密钥);session id字段是用于维持会话,如果客户端与服务端关闭会话之后,客户端又要重新发起会话,session id可用于双方协商是否要进行重新握手过程;extension字段用于添加一些拓展功能;compress表示支持的压缩方法。
    avatar

  • server hello:server hello是根据客户端发送过来的密码套件和压缩方法选择双方都支持的类型,同时服务器端也会生成一个随机数,双方都要保存。

    avatar

  • certificate:该过程中服务器用私钥签名证书,发送给客户端以认证身份

    avatar

  • server key exchange:对于ECDHE_RSA密钥交换算法来说这一过程是必须的,在此过程服务端将生成一对公钥和私钥,私钥保留(用于服务器端生成预主密钥),并将公钥发送给客户端(用于客户端生成预主密钥),同时将前一阶段所有的会话内容利用私钥进行前面发给客户端,用于验证服务端身份,防止中间人攻击。而对于RSA_RSA密钥交换算法,没有这一过程,同样有这个过程的还有DHE密钥交换算法,有没有这一过程都是却决于密钥交换算法自身。在这个数据包中,还给出了服务端生成公私钥所用的算法sec256r1
    avatar

  • server hello done:表示server hello结束,这是个空消息
    avatar

  • client key exchange:客户端也生成一对公钥和私钥,私钥保留(用于客户端生成预主密钥),公钥发给服务端(用于服务端生成预主密钥)
    avatar

  • change cipher spec:客户端根据交互过程中获得的信息,以及应用服务端规定的密码套件,已经生成了相应的密钥。通过这条消息,客户端告诉服务器端:从现在起,我将使用双方约定的密码规范进行通信
    avatar

  • encrypted handshake message:客户端利用生成的密钥加密一段finishde数据传送给服务端,此数据是为了在正式传输应用之前对刚刚握手建立起来的加解密通道进行验证
    avatar

  • new session ticket:服务端告知客户端将生成新的session ticket用于保持会话(session ticket与前面提到的session id作用类似,但两者实现方式不同)

    avatar

  • change cipher spec:同样服务端也要发送这段信息,作用与客户端一致

  • encrypted handshake message:作用与客户端一致
    至此,握手协议结束,双方开始建立加密通道。

  值得注意的是在这个过程中客户端和服务器端都各自产生一对公钥和私钥还有一个随机数,这些都是作为生成预主密钥的元素。预主密钥分别在客户端和服务器端生成,算法的特性能够保证二者生成的预主密钥相同。那么由预主密钥如何生成会话密钥呢,这就要用到前面提到的伪随机函数,通过预主密钥我们将生成客户端验证密钥、服务器端验证密钥、客户端加密密钥、服务器端加密密钥以及客户端分组加密的初始向量和服务器端的分组加密初始向量,具体生成过程可以参考这篇博客。对基于DH算法和RSA算法的握手过程可以参见下图,也可以参考这篇博客

avatar

avatar

前向安全


  在这里有必要提一下关于前向安全的定义:前向安全或前向保密,有时也被称为完美前向安全(Perfect Forward Secrecy,缩写:PFS),是密码学中通讯协议的安全属性,指的是长期使用的主密钥泄漏不会导致过去的会话密钥泄漏。前向安全能够保护过去进行的通讯不受密码或密钥在未来暴露的威胁。如果系统具有前向安全性,就可以保证在主密钥泄露时历史通讯的安全,即使系统遭到主动攻击也是如此。在传输层安全协议(TLS)中,提供了基于迪菲-赫尔曼密钥交换(DHE)的前向安全通讯,分别为(DHE-RSA)和DHE-DSA),还有基于椭圆曲线迪菲-赫尔曼密钥交换(ECDHE)的前向安全通讯,包括(ECDHE-RSA与ECDHE-ECDSA)。理论上,从SSLv3开始,就已经可以使用支持前向安全的密码算法进行通讯。之前我们提到ECDHE算法在sever key exchage阶段会生成一个临时的公私钥对,公钥发送给用户,私钥用于对数据进行RSA签名来验证服务器的身份,如果服务器的私钥泄露,这些会话不会受到影响,无法解密。对于有些算法而言,它在握手过程中不会有这个生成公私钥对的过程,它将使用服务器的私钥进行签名。如果服务器的私钥泄露,这些会话都将被暴露,这就是所谓的前向安全。

openssl


    本文作者:光阴的故事

    本文链接: TLS.html/

    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!
坚持原创技术分享,您的支持将鼓励我继续创作!