zoukankan      html  css  js  c++  java
  • HTTPS原理

    概述

    HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer),是一种基于SSL/TLS的HTTP,所有的http数据都是在SSL/TLS协议封装之上传输的。HTTPS协议在HTTP协议的基础上,添加了SSL/TLS握手以及数据加密传输,也属于应用层协议。所以,研究HTTPS协议原理,最终其实是研究SSL/TLS协议。

    SSL协议,是一种安全传输协议,最初是由 Netscape 在1996年发布,由于一些安全的原因SSL v1.0和SSL v2.0都没有公开,直到1996年的SSL v3.0。TLS是SSL v3.0的升级版,目前市面上所有的HTTPS都是用的是TLS,而不是SSL。

    基本的运行过程

    SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

    但是,这里有两个问题:

    1 如何保证公钥不被篡改?
       解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
    
    2 公钥加密计算量太大,如何减少耗用的时间?
       解决方法:每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。
    

    因此,SSL/TLS协议的基本过程是这样的:

    1 客户端向服务器端索要并验证公钥。
    2 双方协商生成"对话密钥"。
    3 双方采用"对话密钥"进行加密通信。
    

    上面过程的前两步,又称为"握手阶段"(handshake)。

    TLS握手

    TLS的握手阶段是发生在TCP握手之后。握手实际上是一种协商的过程,对协议所必需的一些参数进行协商。TLS握手过程分为四步:

    Client Hello

    在这一步客户端需要想服务器提供如下信息:

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

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

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

    Server Hello

    上图中,从Server Hello到Server Done,有些服务端的实现是每条单独发送,有服务端实现是合并到一起发送。Sever Hello和Server Done都是只有头没有内容的数据。

    服务端在接收到客户端的Client Hello之后,服务端需要将自己的证书发送给客户端。这个证书是对于服务端的一种认证。例如,客户端收到了一个来自于称自己是www.alipay.com的数据,但是如何证明对方是合法的alipay支付宝呢?这就是证书的作用,支付宝的证书可以证明它是alipay,而不是财付通。证书是需要申请,并由专门的数字证书认证机构(CA)通过非常严格的审核之后颁发的电子证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。另外,证书还有个有效期。

    在服务端向客户端发送的证书中没有提供足够的信息的时候,还可以向客户端发送一个Server Key Exchange。

    此外,对于非常重要的保密数据,服务端还需要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端可以向客户端发出Cerficate Request消息,要求客户端发送证书对客户端的合法性进行验证。

    跟客户端一样,服务端也需要产生一个随机数发送给客户端。客户端和服务端都需要使用这两个随机数来产生Master Secret。

    最后服务端会发送一个Server Hello Done消息给客户端,表示Server Hello消息结束了。

    总之,服务器回应的内容包括:

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

    Client Key Exchange

    如果服务端需要对客户端进行验证,在客户端收到服务端的Server Hello消息之后,首先需要向服务端发送客户端的证书,让服务端来验证客户端的合法性。

    在此之前的所有TLS握手信息都是明文传送的。在收到服务端的证书等信息之后,客户端会使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫PreMaster Secret,很多材料上也被称作PreMaster Key, 最终通过Master secret生成session secret, session secret就是用来对应用数据进行加解密的。PreMaster secret属于一个保密的Key,只要截获PreMaster secret,就可以通过之前明文传送的随机数,最终计算出session secret,所以PreMaster secret使用RSA非对称加密的方式,使用服务端传过来的公钥进行加密,然后传给服务端。

    接着,客户端需要对服务端的证书进行检查,检查证书的完整性以及证书跟服务端域名是否吻合。

    ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件的状态,准备使用之前协商好的加密套件加密数据并传输了。

    在ChangecipherSpec传输完毕之后,客户端会使用之前协商好的加密套件和session secret加密一段Finish的数据传送给服务端,此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。

    客户端的回应内容包括:

    1 一个随机数。该随机数用服务器公钥加密,防止被窃听。
    2 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
    3 客户端握手结束通知,表示客户端的握手阶段已经结束。这个阶段会加密一段数据,发送到服务器,供服务器校验。
    

    Server Finish

    服务端在接收到客户端传过来的PreMaster加密数据之后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端同样的方式生成session secret,一切准备好之后,会给客户端发送一个ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和session secret加密数据了。之后,服务端也会使用session secret加密后一段Finish消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。

    根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的session secret对数据进行加密传输了。

    服务器回应内容包括:

    1 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
    2 服务器握手结束通知,表示服务器的握手阶段已经结束。这个阶段会加密一段数据,发送给客户端,供客户端校验。
    

    PreMaster/Master Secret计算

    用三个数生成“会话密钥”的原因

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

    计算过程

    其中Client Random是在Client Hello阶段客户端发送给服务器的,Server Random是在Server Hello阶段服务器发送给客户端的,最终都是用来计算Master Secret的。

    至于PreMaster Secret的计算,主要是通过RSA或者Diffie-Hellman算法生成。我们可以看出,由于在Say Hello阶段,随机数都是明文传送的,如果PreMaster Secret泄漏的话,会导致整个SSL/TLS失效。

  • 相关阅读:
    RocketMQ源码分析:(二)消息发送的三种方式
    LTS本地搭建详述
    Mac端解决(含修改8.0.13版的密码):Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
    flink入门:01 构建简单运行程序
    rocketmq控制台搭建(rocketmq-console)
    在consul上注册web服务
    将filenames里的每个字符串输出到out文件对象中注意行首的缩进
    spidermark sensepostdata ntp_monlist.py
    HTTP Error 403没有了,但是中文全都是乱码。又是怎么回事?
    original.txt和提交的页面输出的文字的混合文件
  • 原文地址:https://www.cnblogs.com/coderland/p/5902621.html
Copyright © 2011-2022 走看看