• HTTPS通讯过程


    这张图清楚的描述了客户端和服务器之间发生了什么。只要你理解了这张图,你就理解了HTTPS通讯过程。

    (这张图取自https://www.researchgate.net/figure/HTTPS-message-sequence-diagram-with-detailed-TLS-handshaking-steps_fig1_306187575)

     

    这张图包括了TCP握手过程和TLS握手过程,我们这里只看TLS握手过程。HTTPS实际就是HTTP+TLS. TLS的握手过程就是HTTPS的握手过程。

    第一步:Client say Hello

             客户端率先发给服务器消息:“你好”。意思是,我准备和你通讯。这组“你好”的消息还包括下面这些信息。

    1. TLS Version. 这是我的TLS版本号
    2. A list of cipher suite 这些是客户端支持的加密算法
    3. SessionID 上图里没提。这是上一个连接的SessionID,如果是新建连接,它是空。
    4. A random number 这是一个随机数,后面要用到。
    5. A list of compression method 一组压缩方法,这不是重点。(感兴趣可看: https://tools.ietf.org/html/rfc3749#page-4)

    这些信息在ClientHello的代码中是像下面这样的。

    struct {

           ProtocolVersion client_version;

           Random random;

           SessionID session_id;

           CipherSuite cipher_suites<2..2^16-2>;

           CompressionMethod compression_methods<1..2^8-1>;

           select (extensions_present) {

               case false:

                   struct {};

               case true:

                   Extension extensions<0..2^16-1>;

           };

       } ClientHello;

    第二步. 服务器回复一个ServerHello,其内容如下

              struct {

              ProtocolVersion server_version;

              Random random;

              SessionID session_id;

              CipherSuite cipher_suite;

              CompressionMethod compression_method;

              select (extensions_present) {

                  case false:

                      struct {};

                  case true:

                      Extension extensions<0..2^16-1>;

              };

          } ServerHello;

    1. TLS 版本
    2. 随机数,后面用
    3. 加密算法
    4. SessionID,上一个连接的SessionID。第一次建立连接,它是空
    5. 压缩方法。

    第三步:服务器发送给客户端服务器的证书。

    第四步:客户端验证服务器的证书。证书的验证过程:

                      https://www.weibo.com/ttarticle/p/show?id=2309404446091184570538

                      然后,客户端生成一个pre-master secret. 接着用服务器证书里的公钥加密这个pre-master secret,发送给服务器。

             我不知道怎么样用中文称呼pre-master secret才好,它其实就是一个随机数。

    PreMasterSecret的结构如下,它包括2个byte的客户端协议版本号和46个byte的随机数,所以,pre-master secret一共是48个byte.

    struct {

               ProtocolVersion client_version;

               opaque random[46];

           } PreMasterSecret;

    第五步:服务器用自己的私钥解开pre-master secret, 然后用客户端的随机数、服务器的随机数和pre-master secret这三个参数计算出一个master secret作为对称加密的会话秘钥。

             客户端也用这三个参数计算出同样的master secret. 这样,客户端和服务器拥有了一样的会话秘钥。

    master_secret的计算函数是下面这样子的。PRF是伪随机函数(pseudo-random function),它接受3个参数,第二个参数是个简单的写死的字符串。

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

    接下来,客户端和服务器就会协商出一种加密算法并用这种算法加密消息,后续的应用层面的数据通讯便都用对称加密的方式通讯。

    一些问题:

    1. 网络监听者能破解pre-master secret吗?

    不能,因为他没有私钥。所以,他也无法知道对称秘钥。

    1. 客户端用来加密的公钥可靠吗?

    可靠。因为证书是经过客户端验证的,验证成功则表明证书合法,证书合法则公钥可靠。

    1. 为什么需要随机数?

    是为了防止重放攻击。网络攻击者虽然不能破解数据包,但他可以重新发送数据包,以达到欺骗系统的目的。使用随机数可以防止这种情况发生,如果网络攻击者重发握手数据包,则服务器会生成新的随机数,服务器端的master_secret会不一样。被中间人重发的应用层面的数据包服务器就不会认得,连接中断。

    1. 如果浏览器被控制和破解了,pre-master secret是不是泄露了?

    应该是的。但这种破解已经不是“中间人攻击”范畴了。现在的机制,是为了防止中间人攻击。

    参考:https://tools.ietf.org/html/rfc2246#page-11

  • 相关阅读:
    Java 代码中如何调用 第三方Api
    如何编写README.md
    Gof 设计模式
    系统架构师-笔记
    我的账户
    软件设计师-成绩查询
    spring data jpa
    日志 logback
    spring boot 整合 Camunda
    Spring 中 bean 的生命周期?
  • 原文地址:https://www.cnblogs.com/dapplehou/p/12737897.html
Copyright © 2020-2023  润新知