真正深度去解析技术的文章越来越少了,而且百度基本搜索不出来这一类的文章(其实很大一部分的原因不是百度没有能力而是人家的平台主动屏蔽了百度的爬虫),本文站在前人的肩膀上试图以浅显易懂的语言解释一下SSL的原理以及为什么SSL是安全的。

什么叫做SSL

HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版(HTTP+SSL)。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

为了描述的简单性,本文中默认对称加密使用的算法为DES,非对称加密的算法使用的是RSA

SSL使用到的技术

  • 秘钥交换算法(自己去搜索吧,我忘记叫啥了)
  • 秘钥传输保密算法(这个是用的非对称加密,一般为RSA,HTTPS网站的证书里面所带的就是RSA的一个公钥)
  • 数据加密算法(这个使用的是对称加密算法,DES这种,然后为了保证安全,每个链接使用的秘钥是不同的)
  • 数据完整性摘要算法(MAC验证,一般算法为MD5或者SHA-1这种)

首先,很重要的一点,要搞明白的就是SSL在进行传输数据加密解密所使用的算法为对称加密,相对于非对称加密,对称加密被破解的风险会更高,但是因为非对称加解密的效率实在太低,所以传输数据的过程中采用的是使用秘钥进行加密的对称加密的算法,例如DES。但是接下来怎么让服务器和客户端使用相同的秘钥进行数据的加解密就成了问题,所以为了秘钥的传输的安全性,在进行秘钥交换(DES的秘钥)的过程中使用RSA进行秘钥传输的安全性加密。然后秘钥交换算法是干什么的呢?其实在进行DES的秘钥传输的过程中,传输的并非是真实使用的加密的密钥,而是用来生成密钥的一个叫做二级密钥的内容,然后通过一系列的复杂的数学运算,来得到真实的密钥。

具体的交换的数学公式为(g^b%p)^a%p=(g^a%p)^b%p,简单理解为一个素数的b次幂对于某个数取余然后在进行a次幂再对该数取余等于将两个幂次的操作交换过来,所以实际上传输的过程中,只要两端同时知道参与操作的g跟用来取余的p,然后双方只要把自己选定的一个幂次传输给对方,即能完成对于秘钥的交换,即客户端只要通知服务器我要使用的数字为a,而服务器只要告诉客户端我选用的数字为b,即可运算得到相同的结果作为密钥。

记住一点,DES进行数据加密,RSA对DES使用的秘钥进行加密(只需要进行一次即可)

对于SSL的密钥交换算法的一些分析可以看一下下面的文章:

https://evergreen-tree.github.io/articles/2016-05/daily-java-keytool-ssl-cacerts

SSL协议的工作过程

SSL协议栈

SSL位于应用层和传输层之间,它可以为任何基于TCP等可靠连接的应用层协议提供安全性保证。SSL协议本身分为两层:

  • 上层为SSL握手协议(SSL handshake protocol)、SSL密码变化协议(SSL change cipher spec protocol)和SSL警告协议(SSL alert protocol);
  • 底层为SSL记录协议(SSL record protocol)。

其中:

  • SSL握手协议:是SSL协议非常重要的组成部分,用来协商通信过程中使用的加密套件(加密算法、密钥交换算法和MAC算法等)、在服务器和客户端之间安全地交换密钥、实现服务器和客户端的身份验证。
  • SSL密码变化协议:客户端和服务器端通过密码变化协议通知对端,随后的报文都将使用新协商的加密套件和密钥进行保护和传输。
  • SSL警告协议:用来向通信对端报告告警信息,消息中包含告警的严重级别和描述。
  • SSL记录协议:主要负责对上层的数据(SSL握手协议、SSL密码变化协议、SSL警告协议和应用层协议报文)进行分块、计算并添加MAC值、加密,并把处理后的记录块传输给对端。

刚才已经解释过秘钥交换的算法,这里面相对深入些分析一下SSL握手和传输的过程。

SSL握手主要解决两件事情(完全对应于上面所说的SSL的四个技术),协商加密算法(包含密钥交换算法,加密算法和完整性验证的),交换加密密钥。

SSL协议栈

上图是一个只验证服务器的SSL的做法(我们日常的浏览器的做法):

只需要验证SSL服务器身份,不需要验证SSL客户端身份时,SSL的握手过程为:

    1. SSL客户端通过Client Hello消息将它支持的SSL版本、加密算法、密钥交换算法、MAC算法等信息发送给SSL服务器。
    1. SSL服务器确定本次通信采用的SSL版本和加密套件,并通过Server Hello消息通知给SSL客户端。如果SSL服务器允许SSL客户端在以后的通信中重用本次会话,则SSL服务器会为本次会话分配会话ID,并通过Server Hello消息发送给SSL客户端。
    1. SSL服务器将携带自己公钥信息的数字证书通过Certificate消息发送给SSL客户端。
    1. SSL服务器发送Server Hello Done消息,通知SSL客户端版本和加密套件协商结束,开始进行密钥交换。
    1. SSL客户端验证SSL服务器的证书合法后,利用证书中的公钥加密SSL客户端随机生成的premaster secret,并通过Client Key Exchange消息发送给SSL服务器。
    1. SSL客户端发送Change Cipher Spec消息,通知SSL服务器后续报文将采用协商好的密钥和加密套件进行加密和MAC计算。
    1. SSL客户端计算已交互的握手消息(除Change Cipher Spec消息外所有已交互的消息)的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并添加MAC值、加密等),并通过Finished消息发送给SSL服务器。SSL服务器利用同样的方法计算已交互的握手消息的Hash值,并与Finished消息的解密结果比较,如果二者相同,且MAC值验证成功,则证明密钥和加密套件协商成功。
    1. 同样地,SSL服务器发送Change Cipher Spec消息,通知SSL客户端后续报文将采用协商好的密钥和加密套件进行加密和MAC计算。
    1. SSL服务器计算已交互的握手消息的Hash值,利用协商好的密钥和加密套件处理Hash值(计算并添加MAC值、加密等),并通过Finished消息发送给SSL客户端。SSL客户端利用同样的方法计算已交互的握手消息的Hash值,并与Finished消息的解密结果比较,如果二者相同,且MAC值验证成功,则证明密钥和加密套件协商成功。

其中1,2两步为协商加密算法,为什么需要协商呢,因为服务器也好,浏览器也好都内置了不止一种加密算法,所以要选择一种两个人都觉着OK的,这一步选择的加密算法是浏览器支持的在服务器端存在的第一个加密算法。

3,4,5,6步为交换密钥,就是客户端发送给服务器端某个二级密钥,然后服务端和客户端分别生成相同的加密密钥(DES密钥)的过程,其中为了保证传输的安全性,第5步的传输用的是第三步传输过来的RSA的私钥进行加密后的数据。

7,8,9为检验前面所做的算法和密钥交换结果的步骤,原理就是用前面协商好的加密算法和密钥进行某个标记的加密,验签(所谓的数字签名,或者叫做MAC验证)和传输。

通过上面的介绍我们可以看到在使用SSL的过程中,除了服务端跟浏览器,其他的中间人想要获取协商的密钥是很困难的(RSA的解密很困难,然后即便解开了,你拿到的也是密钥交换算法中的一个二级密钥,也无法运算出主密钥,所以需要同时知道服务端跟客户端给出的用来运算的二级密钥以及算法才行-参照开始的密钥交互算法),而且因为互联网应用的特殊性,每次用户在某个site上面的连接的时间都是有时效性的,这就导致加密数据的密钥的时效性,所以目前对于SSL并没有特别好的攻击方案,当然手头有比较好的计算机的人除外,也许可以在几个小时甚至更短的时间完成中间人攻击,但是因为牵扯到时效性,造成的破坏也比较有限。

参照文档:

http://www.symantec.com/connect/blogs/how-does-ssl-work-what-ssl-handshake

http://iluoxuan.iteye.com/blog/1736275

https://segmentfault.com/a/1190000002554673