浅谈HTTPS(SSL/TLS)原理

96
出走的流星
0.1 2017.03.23 19:46* 字数 7731

目录

一、https概述

      1.    什么是HTTP?

      2.    什么是HTTPS?

      3.    SSL/TLS

      4.    Openssl

二、基础知识储备

      1.    SNI概述

      2.    公钥基础设施PKI概述

            2.1    PKI的信任服务

            2.2    PKI标准

            2.3    PKI体系结构

      3.    CA中心

            3.1    CA的主要职责

      4.    证书相关常识

            4.1    公钥

            4.2    私钥

            4.3    CSR文件

            4.4    OCSP在线证书状态

            4.5    CRL证书吊销列表

      5.    证书链

      6.    加密算法概述

            6.1    对称加密算法

            6.2    非对称加密算法

            6.3    信息摘要算法

            6.4    HMAC

三、    TLS握手

      1.    ClientHello

      2.    Server Hello

      3.    CertificateServer Key Exchange,Server Hello Done

      4.    Client Key Exchange

      5.    New Session Ticket

      6.    master secret

四、TLS握手概述版

五、HTTPS的优化

六、参考文献


一、https概述

1.    什么是HTTP

在了解https之前,我们首先来了解一下什么是http。http即Hypertext transfer protocol,超文本传输协议,是互联网上应用最为广泛的一种网络协议,由万维网协会(World Wide Web Consortium,W3C)和互联网工程任务组(Internet

Engineering Task Force,IETF)制定标准,其中著名的RFC2616定义了http1.1。设计之初的目的是为了提供一种发布和接收html页面的方法,由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

HTTP是一个C/S架构,由终端用户通过使用浏览器或其它工具发起的一个http请求到服务器指定的端口上获取数据内容,默认为80端口,工作在OSI七层参考模型的应用层上。

http协议到现在已经演化出了很多版本,大部分向下兼容,目前版本有0.9、1.0、1.1及HTTP/2,其中0.9版本已经过时不在使用,主流版本为1.1,未来版本为2.0。

http协议为明文传输,所有信息均为可见的,存在不安全特性,信息极易被篡改和劫持,也因此衍生出了相对更为安全的https。

2.    什么是HTTPS

      HTTPS(Hyper Text Transfer Protocol Secure),即超文本传输安全协议,也称为http over tls等,是一种网络安全传输协议,其也相当于工作在七层的http,只不过是在会话层和表示层利用ssl/tls来加密了数据包,访问时以https://开头,默认443端口,同时需要证书,学习https的原理其实就是在学习ssl/tls的原理。

3.    SSL/TLS

      SSL(Secure Sockets Layer),即安全套接层,是一种安全协议,目的是为互联网通信提供安全及数据完整性保障,使用X.509认证,网景公司(Netscape)在1994年推出HTTPS协议,以SSL进行加密,这是SSL的起源。IETF将SSL进行标准化,1999年公布第一版TLS标准文件。SSL目前有三个版本,SSL1.0、SSL2.0、SSL3.0,因其存在严重的安全问题,大多数公司目前均已不在使用了。因此本文着重是基于TLS讲解。

      TLS(Transport Layer Security),即安全传输层,IETF将SSL标准化后的产物。其实TLS可以理解为SSL的升级版,TLS目前也有三个版本,TLS1.0、TLS1.1、TLS1.2,TLS目前只是草案,并未面世,目前常用的为TLS1.2,server配置通常三个版本均支持。

      扩展知识:X.509标准。SSL证书格式遵循X.509标准,X.509是由国际电信联盟(ITU-T)制定的数字证书标准,ITU于1988年制订了X.500系列标准,其中X.500和X.509是安全认证系统的核心,X.500定义了一种区别命名规则,以命名树来确保用户名称的唯一性,X.509则为X.500用户名称提供了通信实体鉴别机制,并规定了实体鉴别过程中广泛适用的证书语法和数据接口,X.509称之为证书。X.509给出的鉴别框架是一种基于公开密钥体制的鉴别业务密钥管理,即一个用户有两把密钥,公钥和私钥,同时该标准也规范了公开密钥认证、证书吊销列表、授权证书、证书路径验证算法等。

X.509标准知识来源:http://itrus.com.cn/2009/1126/235.html

4.    Openssl

Openssl计划在1998年开始,其目标是发明一套自由的加密工具,在互联网上使用,它是一个开源的加密库,由C语言写成,SSL/TLS协议基于该库进行的加解密。

Openssl支持多种不同的加密算法:

加密:

    AES、Blowfish、Camellia、SEED、DES、RC2、RC4、RC5等

散列函数:

    MD5、MD2、SHA-1、SHA-2、RIPEMD-160 等

公开密钥加密:

    RSA、DSA、Diffie-Hellman key exchange(DH)等

    Openssl不仅包含加密库,同时也是一个小型的CA程序,它可以帮助你完成一个CA的建设,具体参数可以通过man帮助来查看学习,这里暂时先不讲这方面了。

二、基础知识储备

1.    SNI概述

      https是http构建在SSL之上的一种协议,SSL加密在到达应用层的时候就已经完成了,http层完全不知道下面发生了什么。根据https的工作原理,浏览器在访问一个https站点时候,会先与服务器建立ssl连接,建立连接的第一个步骤就是要请求服务器证书,而服务器这个在发送证书的时候,是不知道浏览器访问的是哪个域名的,所以无法根据不同的域名发送不同的证书,也因此有了众所周知的事情,https往常在使用的时候必须要一个IP绑定一个证书,多个证书就要绑定在多个不同的IP之上,这个在我做CDN的HTTPS加速时饱受了痛苦,通常业务量大的时候一个设备就绑定了20多个IP,分别对应不同的证书,管理起来异常的麻烦。那么有没有一种技术即可以节省IP,又可以减少配置工作呢?答案是肯定的,为了解决这一问题,SNI技术应运而生了。

      SNI(Server Name Indication),即服务器名称指示,是一个扩展的TLS协议,在该协议下,在握手过程开始时就可以通过客户端告诉它正在连接的服务器的主机名称,这就允许了服务器在相同的IP地址和TCP端口号上绑定多个证书了,并且因此允许在相同的IP地址上提供多个安全的https网站,它与虚拟主机概念相同。

SNI通过让客户端发送主机名作为TLS协商的一部分来解决此问题,这就使得服务器能够提前选择正确的主机名,并向浏览器提供包含正确名称的证书。SNI需要客户端浏览器和server端程序同时支持,目前主流的浏览器和server端程序均已支持了该特性,近年来IE6的市场份额应该可以小到忽略不计了。

以百度为例,SNI请求的字段数据包如下例子:

详细释义见RFC6066.

2.    公钥基础设施PKI概述

      说到HTTPS就不得不提及一下PKI,PKI(Public key Infrastructure)即公钥基础设施,简单的说PKI技术就是利用公钥理论和技术建立的提供信息安全服务的基础设施,该体系在统一的安全认证标准和规范基础上提供在线身份认证,是CA认证、数字证书、数字签名以及相关安全应用组件模块的集合。做为一种技术体系,PKI可以作为支持认证、完整性、机密性和不可否认性的技术基础,从技术上解决网上身份认证、信息完整性的抗抵赖等安全问题,为网络应用提供可靠的安全保障,但PKI不仅仅涉及到技术层面的问题。

2.1    PKI的信任服务

      a)    认证

      b)    支持密钥管理

      c)    完整性与不可否认

2.2    PKI标准

      a)    X.209(1988)ASN.1基本编码规则的规范

      b)    X.500(1993)信息技术之开放系统互联:概念、模型及服务简述

      c)    X.509(1993)信息技术之开放系统互联:鉴别框架

      d)    PKCS系列标准

      e)    OCSP在线证书状态协议

      f)     LDAP轻量级目录访问协议

2.3    PKI体系结构

      a)    认证机构CA(Certificate Authority)

      b)    证书和证书库

      c)    密钥备份及恢复

      d)    密钥和证书的更新

      e)    证书历史档案

      f)     客户端软件

      g)    交叉认证

      以上内容不做过多的概述,因为跟学习这个没有什么太大的直接关系,可做为了解,其中CA中心会扩展一下。

3.    CA中心

      认证机构CA(Certificate Authority)在https中是一个很重要的角色,CA是PKI的核心执行机构,是PKI的主要组成部分,通常称之为认证中心,从广义上讲,认证中心还应该包括证书申请注册机构RA(Registration Authority),它是数字证书的申请注册、证书签发的管理机构。客户端是怎么验证该证书的颁发机构即CA中心是合法有效的呢,其实在系统浏览器中有预埋CA中心的根证书,在其中的根证书为可信任机构,如图:


根证书可信任机构

3.1    CA的主要职责

      a)笼统的说CA中心负责证书的签发和管理等;

      b)验证并标识证书申请者的身份,对证书申请者的信用度、申请证书的目的、身份的真实可靠性等问题进行审查,确保证书与身份绑定的准确性;

      c)确保CA用于签名证书的非对称密钥的质量和安全性;

      d)管理证书信息资料,管理证书序号和CA标识,确保证书主体标识的唯一性,防止证书主  体名字的重复。在证书使用中确定并检查证书的有效期,保证不使用过期或已作废的证书,    确保网上交易安全,发布和维护作废证书列表(CRL)。

      由此可见,CA是保证电子商务、网上银行、互联网环境健康等的权威性、可信任和公正的第三方机构。

4.    证书相关常识

4.1    公钥

      公钥(Public-key),即所谓的公共证书,由CA中心颁发的合法文件,可以在互联网传播,谁都可以轻易获取到。公钥证书文件的扩展名实际上只是一种使用习惯上的区别,后缀包括但不仅限于crt、cer、key、der、pem,pem可能包含了公钥和私钥文件,通常可以从pem文件中导出公钥和私钥。公钥中包含颁发给哪个域名,公司名,加密算法,组织机构,有效期等等信息,示例如图:

公钥信息


公钥信息

      当然如果说一个证书只能绑定一个域名的话,100个域名就要100个证书了,这样管理和费用成本都会显著增加,根据不同用户的不同需求,同时CA中心也会根据不同国家国情推出不同的产品,例如一个证书绑定多个单域名或泛域名,这些我们都是可以通过公钥查看出来的,示例如图:

证书备用名称

4.2    私钥

      私钥(private-key),即通常就叫所谓的私钥,私钥在生成CSR文件的时候同时生产,后缀通常为.key,由使用者自己保管,不可在互联网传播,极其重要。

4.3    CSR文件

      CSR(Cerificate Signing Request)文件,即证书请求文件,用于发送给CA中心用来生产公钥,该文件在生成的时候会填写一些基本信息,诸如国家代码、公司名、省份城市、管理员邮箱等等信息,可以在线生成也可以通过openssl生成,例:

openssl req -new -nodes -newkey rsa:2048 -keyout xxx.key-out xxx.csr

4.4     OCSP在线证书状态

      OCSP(Online Certificate Status Protocol),即在线证书状态协议,其实就是一个请求应答模式的协议,用于在线的查询证书吊销状态,而无需查询CRL,在对证书状态实时性要求较高的场合适用于使用OCSP来查询当前证书状态。

4.5 CRL证书吊销列表

      CRL(Certificate Revocation List),即证书吊销列表,它指定了一套证书发布者认为无效的证书,CRL一定是被CA所签署的,它可以使用与签发证书相同的私钥,也可以使用专门的CRL签发私钥,CRL中包含了被吊销证书的序列号。通常情况下,公钥证书中会写出该证书的CA中心CRL地址,示例如图:

CRL下载地址

CRL中也会包含一些基本信息,例如列表更新时间,吊销证书序号等,示例如图:

吊销列表
吊销列表

5.    证书链

      简单点阐述证书链就是,为了尽可能的保证根证书的安全性,因此CA中心也采取了一种树状的结构,一个root CA下面包含多个intermediates CA,然后根CA和次级CA都可以颁发证书给用户,颁发的证书分别是根证书和次级证书,最后则是用户的证书,也可以说是中级证书,中级证书可以在CA下载到,这个一般是共通的,证书链的设计是基于“信任链”的理念设计的。            证书链的详尽阐述则需要大家去自行学习了,我对于这个证书链的了解是因为遇到过故障,也因此才了解了证书链是怎么个东西,在之前做https加速的时候,早期的安卓系统版本比较低,在低版本的系统浏览器中访问某些移动网站的时候,会报错,大意就是无法验证这个网站证书是合法的,因为没有证书链,它不知道这个证书的上一级颁发者是谁,新版本的系统及浏览器中则很少见到这种问题。证书链示例如下:


证书链

6.    加密算法概述

6.1    对称加密算法

      对称加密技术(Stmmetric Cryptographic technique),即对称加密技术,发送方和接收方使用相同的算法来进行加解密。

      优点:算法公开,计算量小,加密速度快,效率高。

      缺点:加解密双方使用同样的密钥,安全性得不到保障。

      常见算法:

          DES、3DES、TDEA、RC4、RC5、AES等。

      DES(Data Encryption Standard):数据加密标准,速度快,适用于加密大量数据的场景。

      3DES(Triple Data Encryption Algorithm缩写TDEA,Triple DEA):基于DES,对一块数据应用三次DES数据加密标准算法,强度更高。

      AES(Advanced Encryption Standard):高级加密标准,是下一代加密算法标准,速度快,安全级别高。

6.2    非对称加密算法

      非对称加密技术(asymmetric crypto-graphic technique),即采用了两种相关变换的密码技术,也就是公钥和私钥,公钥加密私钥解密,私钥加密公钥解密。

      常见算法:

          RSA、DSA、ECC、DH等。

      RSA:RSA是1977年由罗纳德·李维斯特(Ron Riverst)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的,当时三人都在麻省理工学院工作,RSA就是他们三人姓氏开头字母的缩写拼在一起组成的。      

      RSA算法的安全性基于大数分解质因子的困难性,由于人们一直未找到对大数进行因子分解的有效方法,所以RSA在目前看来依然是安全的,RSA算法既可用于加密,也可用于签名,是目前应用最广的公钥算法。

      DSA(Digital Signature Algorithm):数字签名算法,基于离散对数难题的,只能用于签名,不能用于加密。

      DH(Diffie-Hellman):是一种安全的密钥交换协议,它可以让双方在完全没有对方任何预先信息的条件下通过不安全通道创建一个密钥,这个密钥可以在后续的通信中做为对称密钥来加密通讯内容。

      该算法详细释义参见维基百科:

 https://zh.wikipedia.org/wiki/%E8%BF%AA%E8%8F%B2-%E8%B5%AB%E7%88%BE%E6%9B%BC%E5%AF%86%E9%91%B0%E4%BA%A4%E6%8F%9B

      ECC(Elliptic curve cryptography),即椭圆曲线密码学,基于椭圆曲线数学。主要优势是在某些情况下它比其他方法使用更小的密钥,提供相当或更高等级的安全。

      该算法详细释义参见维基百科:                            https://zh.wikipedia.org/wiki/%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF%E5%AF%86%E7%A0%81%E5%AD%A6

6.3    信息摘要算法

      信息摘要算法如下:

            md2、md4、md5、sha、sha1等。

      MD5(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,将数据运算变为另一固定长度值是散列算法的基础原理,可以产生一个128位16字节的散列值(hash value),用于确保信息传输完整一致。MD5是可以被破解的,对于需要高度安全的不适用于此摘要算法。

      SHA-1(Secure Hash Algorithm 1),即安全散列算法1,也是一种密码散列函数,美国国家安全局涉及,SHA1可以生成一个被称为消息摘要的160位20字节的散列值,散列值通常呈现形式为40个十六进制数,sha1算法目前也已不在安全,2017年2月23日google与CWI Amesterdam宣布成功完成了一个碰撞攻击。

6.4    HMAC

      HMAC(Keyed-hash message authentication code),即密钥散列消息认证码,又称散列消息认证码,是一种通过特别计算方式之后产生的消息认证码(MAC),使用密码散列函数,同时结合一个加密密钥,它可以用来保证数据的完整性,同时可以用来做某个消息的身份验证,由RFC2104定义,数学公式为:


HMAC数学公式

      其中:

          H为密码散列函数(如MD5或SHA-1)

          K为密钥(secret key)

          m是要认证的消息

           K'是从原始密钥K导出的另一个秘密密钥(如果K短于散列函数的输入块大小,则向右填充(Padding)零;如果比该块大小更长,则对K进行散列)

           ||代表串接

          ⊕代表异或(XOR)

           opad是外部填充(0x5c5c5c…5c5c,一段十六进制常量)

           ipad是内部填充(0x363636…3636,一段十六进制常量)

三、  TLS握手

      TLS握手阶段是发生在TCP建连之后开始进行的,握手其实就是在协商,协商加解密协议所需要的一些参数信息等内容。

      TLS握手过程有单向验证和双向验证之分,简单解释一下,单向验证就是server端将证书发送给客户端,客户端验证server端证书的合法性等,例如百度、新浪、google等普通的https网站,双向验证则是不仅客户端会验证server端的合法性,同时server端也会验证客户端的合法性,例如银行网银登陆,支付宝登陆交易等。

      TLS握手过程如下(图来自RFC5246):

      接下来就以访问百度为例对上述握手过程拆解分析一下,且待我慢慢道来。

1.    ClientHello

      由于客户端对一些加解密算法的支持程度不一样,同时在TLS协议传输阶段必须要使用相同的加密算法才能够保证数据进行正常的加解密,所以在TLS握手阶段,客户端首先要告知server端自己所使用的协议版本号,本地所支持的加密套件列表等信息,除了这些信息以外,客户端还会产生一个随机数,这个随机数保存在客户端的同时会发送给server端,用于后面要产生的master secret即主密钥做准备。

数据包分析如下:

client hello

将该hello包进行拆解分析如下:

a)Record Layer:记录层,记录了该内容的类型为Handshake(22),22则对应下方十六进制的16;

b)Version:TLS1.0(0x0301),该标识记录了TLS1.0实际上是基于ssl3.1而来的,对应下方十六进制为0301;

c)Handshake Type:Client Hello(1),标识了这个握手类型是Client Hello阶段,对应下方十六进制为01;

d)Random:GMT Unix Time时间则为从1970年1月1日至今所经历的秒数,Random

Bytes则为32个字节的随机数,严格点来说就是伪随机数,因为真正的随机数是不存在的;

RFC5246定义如下:

Random
Cipher Suites

e)Session ID Length:顾名思义就是客户端想要用于该连接的Session id,初始值为空,也就是看到的0,因为是第一次访问没有该值;

f)Cipher Suites(15 suites):该字段则为客户端所支持的加密套件,共15套;

g)Extension:该字段就是前文中提到过的SNI相关字段,扩展字段,其中就标识了server name即主机名是什么及字段长度,这样就能在握手时获取主机名并匹配到相对应的证书了;

2.    Server Hello

      Server端在收到客户端发送的Client Hello之后,会回应一个server hello,从server hello到server done,有的server端是会一次性发送完的,如上面RFC握手图中所示的那样,而有些server端会逐条的来发送,同时将公钥发送至客户端。

      同样的,server hello中也包含诸如握手类型,使用的版本号,伪随机数,Session ID,加密套件等信息。

server hello

以上可以看出我们获得了server端的伪随机数,gmt时间以及协商到的加密套件TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

3.    Certificate Server Key Exchange,Server Hello Done

该数据包包含了证书信息以及key exchange等信息,如图:

证书交换

      Server端使用DH算法生成一个pubkey一并发送给client,client在收到pubkey后也计算一个pubkey并发送给server,server来验证是否正确,如果正确则交换信息完成。

      注:这个pubkey具体作用我多方考证加上逻辑推理认为就是这么个作用,如果想错了欢迎指正,我在修改。

4.    Client Key Exchange

      客户端key交换,并且客户端使用change cipher spec通知server端开始使用加密报文传输数据,在此之前的信息都是明文的,因此我可以通过wireshark看到。

      在此阶段,客户端将通过RSA算法生成一个48字节的premaster secret,即预主密钥,这个密钥中包含了客户端tls的版本号信息,如果有中间人共计,有意降低tls版本的话,则会马上终止发送数据。

      这个premaster secret是一个保密的key,只要被截获就可以结合之前明文传输的伪随机数计算出最终的master secret即主密钥。因此该密钥会通过公钥证书加密传送至server端,server端通过私钥进行解密获取预主密钥,此时客户端和server端都有了相同的伪随机数及预主密钥。

5.    New Session Ticket

      该数据包主要是server端向客户端发送新的session ticket,因为最开始并没有这个信息,并通知客户端开始使用加密方式传输数据。

session ticket

      该session ticket就相当于普通网站中的session,当浏览器在次发送请求或者中间网络原因连接被断开之后,client hello阶段携带该session id,则认为是同一个人访问,不在进行证书交互阶段,该session id的复用也是优化的一点,最后会提到。同样的这个数据也是被加密的,server端得到后进行解密即可快速完成握手。其中该字段不仅包含session ticket,还包含ticket的寿命,即过期时间,长度等。

      这里不得不提详细提一下session ticket和session id这两个角色,简单的理解就是session id就是一个session会话标识,当下次访问时携带该标识则认为是同一个人访问,但是假如轮询到集群中其它服务器,则可能无法识别该session id,因为是初次建连服务器给的,而session id是由服务器存储的主要信息,是需要占用服务器内存资源的,且不易扩展。Session id的存储及复用共享需要使用redis或memcache来实现。

      也因此session ticket应运而生了,该字串中包含了当时会话所使用的一些信息,解密出来即可快速重用(RFC5077对此有详细释义),session ticket存储在客户端,新会话后,服务器通过一个自己知道的密钥ticket key将本次会话状态加密,发送给客户端,客户端保存该ticket,下次建连时候发送给server端,该方式的问题是集群中所有server设备使用相同的ticket key,因此也需要考虑该key的轮转及轮转时新旧key兼容的问题。

      nginx会话缓存配置:ssl_session_cachessl_session_ticket_key

      至此整个握手过程已经讲解完成,并且已经开始使用对称密钥传输数据,但是还有一些过程在数据包中是并不能直接体现出来的,因此在后面继续讨论。

6.    master secret

      主密钥,用来对称加密传输数据,主密钥通过客户端random、server端random及premaster secret得到,算法如下:

      master_secret= PRF(pre_master_secret, "master secret", ClientHello.random +ServerHello.random)

      其实我这里并没有理解master secret还没有呢,为啥也参与运算了。

      这里还有一个key block的概念,我因为理解的不太透彻,只能浅显的描述以下了,想仔细的研究还得去看RFC文档。master secret是有一系列的hash值组成的,它将作为数据加解密相关的secret的key material。

      Sessionsecret是从key material中获取,key material经过12次迭代计算,产生12个hash值,分成了6个元素,分别是:

ClientMac(Message Authentication Code)key、server Mac

key、client encryption key、server encryption key、clientIV(Initialization Vector)、serverIV

      我理解最终的对称加密就是使用这几个hash值进行加密解密以及数据完整性的校验,因为客户端和server端两头都有了这几个数据。

      因为对其理解的不太透彻,故此贴出部分RFC释义:

四、TLS握手概述版

      由于以上信息太多,考虑到一般人没心情看完这么多以及只想浅尝辄止,在加上我写了这么多自己已经逻辑混乱了,因此放出概述版,摘自微软。

五、  HTTPS的优化

      目前我头脑中只有两个大的方向。

          a)Session id及session ticket的复用,缩减证书交换时间,减少可能的计算以及RTT时间,例图中所示:

      Session重用之后减少了证书交换等一系列的验证过程,缩减了RTT时间,握手次数,减少了算法加密过程,在简单的交换信息之后就直接开始传输数据了。

      b)选取相对来说计算量较小且安全的算法。

      对于优化只有这两个思路,详细的我现在还无法写出,因为我已经写累了。

六、  参考文献

      维基百科、RFC文档、经验、互联网文章


      以上均为我个人学习理解之后总结的一些内容,一口气写的有点多了,难免有脑子糊涂想错的地方,欢迎大家拍砖勘误,感谢。

      勘误联系方式:  294719425@qq.com

:

日记本