HTTPS运行原理

https

背景

由于 apple 宣布苹果App于2017年1月1日(已宣布延迟)将启用App Transport Security安全功能,即强制App通过HTTPS连接网络服务,这使得大小公司的程序员加班加点切换http到https.

苹果为啥为啥非要切换https,难道是折腾程序员好玩?其实早在2015年9月的WWDC15上,苹果公司就提出了ATS(App Transport Security),所谓的ATS是一种新型加密技术-Forward Secrecy,要求应用与后台通讯必须使用最新的TLS1.2版本Https协议,以及所有Apple Store中的App必须使用SHA256算法的SSL/TLS证书。苹果提出这个战略的原因是:随着全球互联网安全意识的进一步觉醒,越来越多的公司意识到网络信息安全的重要性,只有绝对的加密才能保证在线交易和商务活动的安全进行。互联网无疑是个人信息和隐私泄露最频繁的场合,各种以窃取信息为方式而展开的网络犯罪是互联网发展所面临的最大挑战。在这样一个大环境下,苹果公司首先做出应对,强制所有App在2017年1月1日前使用HTTPS加密。所以苹果在“拥抱变化”上还是处理最前沿的,不得不佩服苹果的魄力。

那我们就来看一下https到底是怎么样来保证安全的。

https 原理

https安全性

https 保证了三方面的安全性:

  • 1)加密数据以防止数据中途被窃取
  • 2)认证用户和服务器,确保数据发送到正确的客户机和服务器
  • 3)维护数据的完整性,确保数据在传输过程中不被改变。

我们将围绕这三个点来解释https 的实现原理。

http 与https的差别

想了解https的安全性,首先得了解一下http的不安全性,怎么样也得让http死得明白!

假定一个场景,我们在登录页面,用户输入账号密码进行登录

用户登录->各种路由、代理服务器等->实际授权服务器

我们的账号密码等信息需要经过很长的路径才能到达目标服务器,在到达授权服务器前,账号和密码是光着身子的,任何中间服务器想看几眼都可以。如果你说那我们不可以通过js在前端对账号密码加密吗?当然可以,但无非像黄帝的新装,中间代理服务器仍然可以拍一张裸照,去欺骗授权服务器。

https 就是安全版的http,在http的基础上加了一个TLS/SSL(以下统称SSL,习惯了,至于发展过程详见),如下图.
通俗的讲,TLS、SSL其实是类似的东西,SSL是个加密套件,负责对HTTP的数据进行加密。TLS是SSL的升级版。现在提到HTTPS,加密套件基本指的是TLS。原先是应用层将数据直接给到TCP进行传输,现在改成应用层将数据给到TLS/SSL,将数据加密后,再给到TCP进行传输。
所以下述场景变成了这个样子:

用户登录->加密(穿衣服)-> 各种路由、代理服务器等-> 解密(脱衣服)->实际授权服务器

所以你的信息在传输的过程中就再也不用裸奔了,而且想脱都脱不掉,因为衣服上有把锁,只有服务器的私钥才能打开。

41ea8c52244e27211764eb44902cc6f1.png

所以http和https最重要的区别就是TLS/SSL,https实际上就是在应用层(HTTP) 和传输层(TCP)之间加了一层TSL/SSL

https的握手和加密过程

整个过程分为以下几个步骤:

  • 验证证书有效性(是否被更改,是否合法)
  • 握手生成会话密钥
  • 利用会话密钥进行内容传输

下面我们来看一下整个流程

Image 2017-01-04 at 9.19.45 上午.png

1 客户端发出请求(ClientHello)

客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做ClientHello请求。
在这一步,客户端主要向服务器提供以下信息。

  • (1) 支持的协议版本,比如TLS 1.0版。
  • (2) 一个客户端生成的随机数,稍后用于生成”对话密钥”。
  • (3) 支持的加密方法,比如RSA公钥加密。
  • (4) 支持的压缩方法。

这里需要注意的是,客户端发送的信息之中不包括服务器的域名。也就是说,理论上服务器只能包含一个网站,否则会分不清应该向客户端提供哪一个网站的数字证书。这就是为什么通常一台服务器只能有一张数字证书的原因。

对于虚拟主机的用户来说,这当然很不方便。2006年,TLS协议加入了一个Server Name Indication扩展,允许客户端向服务器提供它所请求的域名。

2/3 服务器回应(SeverHello)

服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。服务器的回应包含以下内容。

  • (1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
  • (2) 一个服务器生成的随机数,稍后用于生成”对话密钥”。
  • (3) 确认使用的加密方法,比如RSA公钥加密。
  • (4) 服务器证书。

除了上面这些信息,如果服务器需要确认客户端的身份,就会再包含一项请求,要求客户端提供”客户端证书”。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。

4 客户端验证证书

客户端收到服务器回应以后,首先验证服务器证书。
如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
验证证书主要根据服务端发过来的证书名称,在本地寻找其低级证书,并一级一级直到根证书,验证各级证书的合法性。证书的详情内容,请见本文附录

5 客户端回应

如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。

  • (1) 一个随机数。该随机数用服务器公钥加密,防止被窃听。
  • (2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
  • (3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。

6 生成会话密钥

上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称”pre-master key”。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把”会话密钥”。

至于为什么一定要用三个随机数,来生成”会话密钥”,dog250解释得很好:

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

服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的”会话密钥”。
此外,如果前一步,服务器要求客户端证书,客户端会在这一步发送证书及相关信息。

7 服务器的最后回应

服务端生成”会话密钥”后,向客户端最后发送下面信息。

  • (1)编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
  • (2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。

至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用”会话密钥”加密内容。

2.3 https 的优势

https有三种优势:

  • 1)加密数据以防止数据中途被窃取
  • 2)认证用户和服务器,确保数据发送到正确的客户机和服务器
  • 3)维护数据的完整性,确保数据在传输过程中不被改变。

通过了解TSL/SSL的工作原理,我们知道:
通讯过程中的hash 生成的摘要,保证了数据的完整性;
握手的非对称加密和传输过程中的对称加密保证了数据的私密性
客户端验证证书以及“金融系统中USB证书”保证了客户端和服务端的真实性。

2.4 如何使用代理(charles)

charles抓包方式
我们知道从https的整个原理来可以知道,客户端和服务端进行通信的过程,客户端能拿到数据,代理也一定能拿到,包括公共密钥、证书、算法等。但代理无法获取服务器的私钥,所以无法获取5/6/7过程中的会话密钥,也就无法得到数据传输过程中明文,所以默认情况下,charles是无法抓https的,或者说抓到的也是乱码。
那如何让charles抓包并获取明文?也就是得让charles获取私钥,获取服务器的是不可能的,那只能在通信过程中使用charles自己的证书,并在通信的过程中主动为请求的域名发放证书。示例流程如下:

Image 2017-01-04 at 10.16.48 上午 (1)的副本.png

从上面可以看出,一旦信任代理的证书,代理在中间就做一个转换的角色,即担任客户端的服务器,又担任服务端的客户端,在中间传输的过程中做了加解密转换。也就是说一旦信任代理,代理就可以干任何事。

2.5 https 的确陷

其实我们在上面已经谈到了,一旦信任CA,CA发放的证书都将成为可信的,CA发放的机构不一定是安全的,特别是自制的证书,一旦信任,在其发放证书的所有服务器上的个人信息都是裸露的状态,要悲的是你又不知道他会用你的信息干啥。所以不要轻易信任第三方证书。

三 附录-证书格式

  1. 证书版本号(Version)
    版本号指明X.509证书的格式版本,现在的值可以为:
    1. 0: v1
    1. 1: v2
    1. 2: v3
      也为将来的版本进行了预定义
  1. 证书序列号(Serial Number)
    序列号指定由CA分配给证书的唯一的"数字型标识符"。当证书被取消时,实际上是将此证书的序列号放入由CA签发的CRL中,
    这也是序列号唯一的原因。

  2. 签名算法标识符(Signature Algorithm).
    签名算法标识用来指定由CA签发证书时所使用的"签名算法"。算法标识符用来指定CA签发证书时所使用的:

    1. 公开密钥算法
    1. hash算法
      example: sha256WithRSAEncryption
      须向国际知名标准组织(如ISO)注册
  1. 签发机构名(Issuer)
    此域用来标识签发证书的CA的X.500 DN(DN-Distinguished Name)名字。包括:
    1. 国家(C)
    1. 省市(ST)
    1. 地区(L)
    1. 组织机构(O)
    1. 单位部门(OU)
    1. 通用名(CN)
    1. 邮箱地址
  1. 有效期(Validity)
    指定证书的有效期,包括:
    1. 证书开始生效的日期时间
    1. 证书失效的日期和时间
      每次使用证书时,需要检查证书是否在有效期内。
  1. 证书用户名(Subject)
    指定证书持有者的X.500唯一名字。包括:
    1. 国家(C)
    1. 省市(ST)
    1. 地区(L)
    1. 组织机构(O)
    1. 单位部门(OU)
    1. 通用名(CN)
    1. 邮箱地址
  1. 证书持有者公开密钥信息(Subject Public Key Info)
    证书持有者公开密钥信息域包含两个重要信息:
    1. 证书持有者的公开密钥的值
    1. 公开密钥使用的算法标识符。此标识符包含公开密钥算法和hash算法。
  1. 扩展项(extension)
    X.509 V3证书是在v2的基础上一标准形式或普通形式增加了扩展项,以使证书能够附带额外信息。标准扩展是指
    由X.509 V3版本定义的对V2版本增加的具有广泛应用前景的扩展项,任何人都可以向一些权威机构,如ISO,来
    注册一些其他扩展,如果这些扩展项应用广泛,也许以后会成为标准扩展项。

  2. 签发者唯一标识符(Issuer Unique Identifier)
    签发者唯一标识符在第2版加入证书定义中。此域用在当同一个X.500名字用于多个认证机构时,用一比特字符串
    来唯一标识签发者的X.500名字。可选。

  3. 证书持有者唯一标识符(Subject Unique Identifier)
    持有证书者唯一标识符在第2版的标准中加入X.509证书定义。此域用在当同一个X.500名字用于多个证书持有者时,
    用一比特字符串来唯一标识证书持有者的X.500名字。可选。

  4. 签名算法(Signature Algorithm)
    证书签发机构对证书上述内容的签名算法
    example: sha256WithRSAEncryption

  5. 签名值(Issuer's Signature)
    证书签发机构对证书上述内容的签名值

推荐阅读更多精彩内容