zoukankan      html  css  js  c++  java
  • SSL/TLS协议簇加解密流程

    一、概述
          SSL协议是最早Netscape公司开发的安全通信协议,用于浏览器安全通信。到SSL Version3,提交作为IFTF草案,已经广泛的应用Intetnet通信。之后IETF对SSLv3稍作改动并更名为TLS1.0,对应RFC2246,之后的TLS1.1、TLS1.2先后被接受为RFC4346,RFC5246,另外由于TLS是基于TCP协议设计,导致其不能处理独立纪录,不允许SSL时有数据丢失,在RFC4347中提出了一种“Datagram TLS”---DTLS,可以理解为TLS1.1的分支。

          SSL/TLS协议的设计目标是保证数据的机密性和完整性。因此在SSL/TLS协议中包含了3类算法:对称加密算法(保证机密性),数据签名算法(保证完整性)和公钥算法(用于交换密钥)。下面以TLS1.0为基准介绍SSL/TLS协议簇加解密流程。

    二、加解密流程
          SSL/TLS协议的基本数据交互流程如下图:

          加解密流程详细介绍如下:

          Client Hello :表示客户端向服务器发起SSL握手请求。
          客户端:生成一个32byte的random用于计算主密钥、加密密钥和消息的数字签名。在cipher suites中指明自己支持的对称加密、非对称加密和数字签名算法。

         
          Server Hello:表示服务器相应客户端的SSL握手请求。
          服务器端:生成一个32byte的random用于计算主密钥、加密密钥和消息的数字签名。生成一个23byte的SessionID。在client cipher suites中挑选一个加密强度最高的算法组合,作为双方的通讯的算法。

          如TLS_RSA_WITH_AES_128_CBC_SHA表示通讯协议时TLS、非对称加密算法为RSA、对称加密算法为AES_128_CBC、数字签名算法为SHA。

         
          Certificate:服务端证书。
          服务器端:如果服务端证书是Base64编码,首先把证书进行Base64解码,得到的是使用ASN.1格式编码的X.509证书。

          证书中的信息包括:

         客户端:根据收到的证书,判断其合法性,并计算得到服务器的公钥(对于RSA算法,是解析得到n和e,对于DH算法解析得到a和q)。

         证书合法性的判断方法:

         ~颁布者的合法性(hash值)

         ~有效期

         ~签名值是否合法:首先对证书中除签名值部分的内容按照证书中的签名

         算法进行签名,把得到的签名按照asn.1编码方式进行编码:OBJECT格式的签名算法+ ASN_OCTET_STRING格式的签名值A;把证书中的签名值按照证书中的主体公钥算法进行解密得到B;当A和B完全相同时认为证书有效(证书制作过程中的签名值计算方法:计算得到A,和客户端计算方法相同,用服务器私钥对A进行加密,得到证书中的签名值)

          一般情况下客户端收到的是一个证书链,第一个是服务器的证书,之后是服务器证书签发者。。。最后是自签名的根证书。如下图。在实际解析中先要验证根CA的证书,然后是直接证书签发者证书,最后是服务器终端证书。

         Certificate Request:当服务器需要验证客户端证书时使用。
        
         Server Key Exchange:用于交换对车密钥,只有在使用RSA扩展选项或者DH算法时才会使用。
     
         Server Hello Done:表示握手消息结束。
     
         Client Key Exchange:交换预主密钥。
         客户端:

               RSA算法:

                     随机生成48byte的预主密钥,把48byte的第一个字节设置成主版本号,第二个字节设置成次版本号。用步骤2中协商得到的非对称加密算法进行加密。传递给服务器端。

               DH算法:

                    得到随机数Xc,计算得到Yc,把Yc通过Client Key Exchange消息明文传递为服务器端;根据a,q,Xc,Ys计算得到预主密钥。

         客户端和服务器端都需要根据预主密钥计算得到主密钥、加密密钥和签名密钥,方法如下:

              RSA算法:     

                    接到客户端加密的预主密钥,按照非对称密钥进行解密,得到预主密钥。然后按照PRF算法计算得到主密钥。(生成主密钥的算法SSL和TLS略有不同。)

              DH算法:

                    根据a,q,Xs,Yc计算得到预主密钥。

              根据预主密钥计算得到主密钥的算法(PRF算法):就是带密钥的MD5签名算法和带密钥SHA签名算法得到的结果异或得到的。

             MD5:

                  密钥:预主密钥的前24byte,签名文本:字符串“master secret”+服务器端32byte的random + 客户端32byte的random,生成48byte的MD5Hash值

             SHA:

                 密钥:预主密钥的后24byte,签名文本:字符串“master secret”+服务器端32byte的random + 客户端32byte的random,生成48byte的SHAHash值

             得到主密钥:MD5Hash XOR SHAHash

             最后根据主密钥计算的到6个实际使用的密钥:client_write_MAC_secret;server_write_MAC_secret;client_write_key;server_write_key;client_write_IV;server_write_IV;

             计算方法和计算主密钥的方法类似,都使用PRF算法。不同的是提供给MD5和SHA的密钥是主密钥,最后生成的Hash长度为148。然后把148byte的Hash依次赋值给上述6个实际密钥。

         Change Cipher Spec:表示之后的消息传输都将采用对称加密方式进行。
         Encryted HandShake Message:加密的Finish报文,用于验证双方协商的对称加密算法、客户端密钥。
     
        ~客户端给服务器发送的Finished报文:
              客户端:对字符串“client finished”应用PRF算法:MD5和SHA的密钥是主密钥,加密的密文是SSL握手以来所有消息的串联,生成的Hash值为12Byte;对生成的12byte应用HMAC算法,算法的密钥是client_write_MAC_secret,把计算得到的MAC值添加到Hash后面;如果是对称加密算法是块加密算法,那么还需要填充pad。最后用第2步中协商的对称加密算法对上述数据进行整体加密,加密密钥是前面中计算得到的client_write_key。

             服务器端:首先用密钥为的client_write_key对称加密算法对数据进行解密,计算字符串“client finished”的MAC值和客户端发送过来的12byte进行比较,相同则认为client_write_key的对称加密正确,再用client_write_MAC_secret计算MAC值,和客户端的数据进行比较,如果相同则认为client_write_MAC_secret正确。

        ~服务器给客户端发送的Finished报文:
        和客户端给服务器发送的Finished报文类似,是对字符串“server finished”进行计算,用于验证server_write_key和server_write_MAC_secret。

      
        APP Data:加密数据。
        服务器端:首先根据client_write_key解密整个消息体,并对其中的实际数据部分进行HMAC(密钥为client_write_MAC_secret)并和客户端发送过来的MAC进行比较,如果相同则认为数据完整。

        客户端:首先根据server_write_key解密整个消息体,并对其中的实际数据部分进行HMAC(密钥为server_write_MAC_secret)并和客户端发送过来的MAC进行比较,如果相同则认为数据完整。

     
    三、协议簇
        上节是以TLS1.0为基准进行说明,但是SSL/TLS协议簇内的协议之间有一定的差别。

    3.1 SSL3.0
     
         生成主密钥
         TLS1.0使用了PRF算法,其核心是分别用MD5和SHA分别计算的到Hash,并把MD5Hash和SHAHash相异或得到主密钥;

         SSL的计算方法:把SHA计算得到的Hash作为MD5的输入,计算得到16byte的Hash值,重复计算3次,把3次计算得到的3个16byte的Hash拼接成主密钥。

         生成计算密钥
         区别同上

         数字签名算法
         对于加密数据的数字签名算法。

         TLS1.0使用了RFC2104定义的HMAC算法:HMAC:MAC = H(Key^oPad,H(Key^iPad , context))

         SSLv3使用的MAC算法和HMAC算法类似:MAC = H(Key+oPad, H(Key+iPad , context))

    3.2 TLS1.1
         加密数据格式
         TLS1.0中块加密数据的格式为

         block-ciphered struct {

             opaque content[TLSCompressed.length];

             opaque MAC[CipherSpec.hash_size];

             uint8 padding[GenericBlockCipher.padding_length];

             uint8 padding_length;

         } GenericBlockCipher;

         TLS1.1块加密数据的格式为

         block-ciphered struct {

              opaque IV[CipherSpec.block_length];

              opaque content[TLSCompressed.length];

              opaque MAC[CipherSpec.hash_size];

              uint8 padding[GenericBlockCipher.padding_length];

              uint8 padding_length;

          } GenericBlockCipher;

          导致在块加密数据解码时有所不同。

    3.3 TLS1.2
         生成主密钥
              默认使用SHA256代替PRF

         生成计算密钥
              默认使用SHA256代替PRF


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sealyao/archive/2010/09/23/5901510.aspx

  • 相关阅读:
    MVC框架及其应用
    《企业应用架构模式》-阅读笔记1
    《架构之美》阅读笔记3
    《架构之美》-阅读笔记2
    《架构之美》阅读笔记1
    一线架构师实践指南第三篇—— Refined Architecture(预习)
    知识图谱_示例图
    一个考研党的敷衍的毕业设计_知识图谱
    一线架构师阅读笔记三
    一线架构师阅读笔记二
  • 原文地址:https://www.cnblogs.com/p2liu/p/6048787.html
Copyright © 2011-2022 走看看