https原理总结

作者 Lei da 日期 2019-07-05
https原理总结

最近在公司项目的服务器上做一些内部接口,要求使用https,于是花时间研究了一波。我们熟知的http在传输时未对数据进行加密,在传输一些敏感信息时存在着不小的安全隐患。因此,https在http的基础上加上了SSL(Secure Sockets Layer)加密,以保障数据的安全传输。如今使用的TLS实际上是SSL的升级版本。具体有关https的概念可参考百科
https介绍

1.https原理探究

https的保障信息安全的机制,其实用一句话就能概括:client与server通过非对称加密来协商一个对称秘钥,然后CS两端使用该对称秘钥来进行数据的加密解密,完成数据交互。所以数据传输时,实际上走的是对称加密。当然理解这句话前提,需要明白对称和非对称加密的原理,本文不做讨论。

原理概况

SSL加密机制的大致过程:

  • client发送请求
  • server返回证书
  • client验证并取出证书中的公钥
  • client生成随机数,并使用服务器公钥将其加密,把得到的密文发送给server
  • server使用私钥解密,得到随机数
  • 两端各自通过随机数生成对称秘钥,协商完成

数字证书与数字签名

在详细介绍握手环节之前,我想先说说数字数字证书的起因及原理,数字证书是整个SSL加密的核心与纽带。首先,在使用非对称加密传输之前,客户端需要获取服务器公钥,这里存在一种攻击方式,即中间方使用自己的公钥替换服务器的公钥发送给客户端,再通过自己的私钥获取客户端传来的非对称加密内容,从而实现篡改以及窃听。为了方便理解,网上有一张图我直接拿来用了,如下所示。
image
为了防止获取公钥过程遭到第三方的掉包等之类的破坏,于是便有了证书机制,下图为服务器证书的签署以及验证的大致流程。
image

证书包含三部分内容

  • 证书内容(服务器公钥、服务器信息等)
  • 加密算法(加密算法、哈希算法)
  • 密文(使用哈希算法计算证书内容得到哈希摘要,再使用CA私钥加密该摘要即得到密文,该过程称为数字签名)

验证数字证书

  • 客户端验证服务器证书时,需要获取到你的上一级CA证书,从而得到取CA公钥,使用CA公钥对证书中的密文解密得到哈希摘要,同时客户端使用同样的哈希算法对服务器证书内容计算得到另一个哈希摘要,若这两个摘要相等,则证明证书合法。

上述的哈希签名也称为数字指纹法,该方法的精髓在于,相同的明文通过哈希计算得到的摘要,一定是相同的,而只要两份明文只要有一丝丝区别,其对应的哈希值也是不同的。因此,若第三方替换了证书中的公钥,根据证书内容计算出的新的摘要一定与密文中的摘要有所差异的,故可以轻松地判断证书不合法。

疑问

(1)既然是使用上级CA证书来验证服务器证书,那如何证明上级CA证书的合法性?

  • 这涉及到一个证书信任链的问题。上级证书通过更高一级的CA根证书来确定其合法性,这是一个递归向上的过程,直到最顶层根证书。顶层CA根证书是整个安全体系的根本。

(2)前文提到的攻击方式,只替换公钥显然是不行,那如果第三方把整个证书都替换成自己的证书(因为CA机构可以给任何人签名,黑客也可以),这样的话客户端的验证是不是可以通过?

  • 答案当然是否定的,很简单,因为证书内容里的服务器信息是唯一的、不可复制的,例如域名,若替换整个证书,域名也会变成黑客自己的域名,浏览器不会接受域名和请求内容不匹配的证书。比如说,浏览器请求了 baidu.com,结果返回了个google.com的证书,毫无疑问会立即排除掉。

保证了服务器公钥安全抵达客户端手中,后续的对话秘钥的协商便也能顺理成章地进行。因此https所采用的SSL机制是绝对安全的,几乎没有人能够破解。当然,有得必有失,https花费的开销也远高于http。

SSL握手过程

https握手原理图

image
理解了上文所讲的证书机制,其实SSL加密机制也基本容易理解了,下面细究一下SSL握手过程,此处结合上方交互原理图进行分析
(1) Client Helllo。客户端发送初次请求,请求内容包含版本信息,加密套件候选列表,压缩算法候选列表,随机数random_1,扩展字段等信息,以明文传输;

(2)服务器选择客户端支持的加密套件、压缩算法、协议版本等,生成随机数random_2;

(3)服务器将上述算法以及随机数等发送给客户端;

(4)服务器发送服务器数字证书;

(5)客户端接收服务器选择的算法以及随机数等,验证数字证书。若证书验证通过,或者用户接受了不可信证书,客户端获取服务器公钥,同时会生成随机数random_3,并使用服务器公钥加密该随机数得到密文;

(6)客户端将第五步得到的密文传给服务器,由于公钥加密的内容只能使用私钥解开,所以random_3无法被窃听;

(7)Change cipher Spec。客户端通知服务器协商完成;

  • 此时客户端已存有三个随机数random_1、random_2和random_3,前两个是可以被截获的,第三个是私密的,根据这三者可计算得出对话秘钥,即enc_key=Fuc(random_1, random_2, random_3)

(8)客户端结合之前所有通信参数的 hash 值与其它相关信息生成一段数据,并使用对话秘钥enc_key和算法将其加密,得到密文encrypted_handshake_message,将其发送给服务器进行验证;

(9)服务器使用私钥解密第六步得到的密文,得到随机数random_3,此时服务器也拥有了三个随机数random_1、random_2和random_3,同样可计算出对话秘钥enc_key,至此双方共享对称加密秘钥的目的已达成;计算之前所有接收信息的 hash 值,然后解密客户端发送的 encrypted_handshake_message,验证数据和密钥正确性;

(10)类似7和8,服务器通知客户端协商完成,同时计算发送encrypted_handshake_message。客户端以同样的方式验证encrypted_handshake_message,握手完成。

完成握手之后,服务器和客户端都使用相同的对话秘钥enc_key,对消息内容进行加密,实现安全通信。