解密https的建立过程

1. https协议简介

     为什么是协议简介呢?因为https涉及的东西实在太多了,尤其是一些加密算法,非常的复杂,对于这些算法面的东西就不去深入研究了,这部分仅仅是梳理一下一些关于https最基本的原理,为后面分解https的连接建立以及https优化等内容打下理论基础。

2. 对称加密算法

     对称加密是指加密和解密使用相同密钥的加密算法。它要求发送方和接收方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信至关重要。

2.1 对称加密又分为两种模式:流加密和分组加密。

      流加密是将消息作为位流对待,并且使用数学函数分别作用在每一个位上,使用流加密时,每加密一次,相同的明文位会转换成不同的密文位。流加密使用了密钥流生成器,它生成的位流与明文位进行异或,从而生成密文。现在常用的就是RC4,不过RC4已经不再安全,微软也建议网络尽量不要使用RC4流加密。

      分组加密是将消息划分为若干位分组,这些分组随后会通过数学函数进行处理,每次一个分组。假设需要加密发生给对端的消息,并且使用的是64位的分组密码,此时如果消息长度为640位,就会被划分成10个64位的分组,每个分组都用一系列数学公式公式进行处理,最后得到10个加密文本分组。然后,将这条密文消息发送给对端。对端必须拥有相同的分组密码,以相反的顺序对10个密文分组使用前面的算法解密,最终得到明文的消息。比较常用的分组加密算法有DES、3DES、AES。其中DES是比较老的加密算法,现在已经被证明不安全。而3DES是一个过渡的加密算法,相当于在DES基础上进行三重运算来提高安全性,但其本质上还是和DES算法一致。而AES是DES算法的替代算法,是现在最安全的对称加密算法之一。分组加密算法除了算法本身外还存在很多种不同的运算方式,比如ECB、CBC、CFB、OFB、CTR等,这些不同的模式可能只针对特定功能的环境中有效,所以要了解各种不同的模式以及每种模式的用途。这个部分后面的文章中会详细讲。

2.2 对称加密算法的优、缺点:

   优点:算法公开、计算量小、加密速度快、加密效率高。
   缺点: (1)交易双方都使用同样钥匙,安全性得不到保证;
            (2)每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。

            (3)能提供机密性,但是不能提供验证和不可否认性。

3. 非对称加密算法

     在非对称密钥交换算法出现以前,对称加密一个很大的问题就是不知道如何安全生成和保管密钥。非对称密钥交换过程主要就是为了解决这个问题,使得对称密钥的生成和使用更加安全。

     密钥交换算法本身非常复杂,密钥交换过程涉及到随机数生成,模指数运算,空白补齐,加密,签名等操作。

     常见的密钥交换算法有RSA,ECDHE,DH,DHE等算法。涉及到比较复杂的数学问题,下面就简单介绍下最经典的RSA算法。RSA:算法实现简单,诞生于1977年,历史悠久,经过了长时间的破解测试,安全性高。缺点就是需要比较大的素数也就是质数(目前常用的是2048位)来保证安全强度,很消耗CPU运算资源。RSA是目前唯一一个既能用于密钥交换又能用于证书签名的算法。我觉得RSA可以算是最经典的非对称加密算法了,虽然算法本身都是数学的东西,但是作为最经典的算法,我自己也花了点时间对算法进行了研究,后面会详细介绍。

     非对称加密相比对称加密更加安全,但也存在两个明显缺点:

  1. CPU计算资源消耗非常大。一次完全TLS握手,密钥交换时的非对称解密计算量占整个握手过程的90%以上。而对称加密的计算量只相当于非对称加密的0.1%,如果应用层数据也使用非对称加解密,性能开销太大,无法承受。
  2. 非对称加密算法对加密内容的长度有限制,不能超过公钥长度。比如现在常用的公钥长度是2048位,意味着待加密内容不能超过256个字节。

4. 身份认证

     https协议中身份认证的部分是由数字证书来完成的,证书由公钥、证书主体、数字签名等内容组成,在客户端发起SSL请求后,服务端会将数字证书发给客户端,客户端会对证书进行验证,并获取用于秘钥交换的非对称密钥。

(1)数字证书有两个作用:
  1. 身份授权。确保浏览器访问的网站是经过CA验证的可信任的网站。
  2. 分发公钥。每个数字证书都包含了注册者生成的公钥。在SSL握手时会通过certificate消息传输给客户端。
(2)申请一个受信任的数字证书通常有如下流程:
  1. 终端实体(可以是一个终端硬件或者网站)生成公私钥和证书请求。
  2. RA(证书注册及审核机构)检查实体的合法性。如果个人或者小网站,这一步不是必须的。
  3. CA(证书签发机构)签发证书,发送给申请者。
  4. 证书更新到repository(负责数字证书及CRL内容存储和分发),终端后续从repository更新证书,查询证书状态等。

(3)数字证书验证

     申请者拿到CA的证书并部署在网站服务器端,那浏览器发起握手接收到证书后,如何确认这个证书就是CA签发的呢?怎样避免第三方伪造这个证书?答案就是数字签名(digital signature)。数字签名是证书的防伪标签,目前使用最广泛的SHA-RSA(SHA用于哈希算法,RSA用于非对称加密算法)数字签名的制作和验证过程如下:
  1. 数字签名的签发。首先是使用哈希函数对待签名内容进行安全哈希,生成消息摘要,然后使用CA自己的私钥对消息摘要进行加密。
  2. 数字签名的校验。使用CA的公钥解密签名,然后使用相同的签名函数对待签名证书内容进行签名并和服务端数字签名里的签名内容进行比较,如果相同就认为校验成功。
(4)需要注意的是:
  1. 数字签名签发和校验使用的密钥对是CA自己的公私密钥,跟证书申请者提交的公钥没有关系。
  2. 数字签名的签发过程跟公钥加密的过程刚好相反,即是用私钥加密,公钥解密。
  3. 现在大的CA都会有证书链,证书链的好处一是安全,保持根CA的私钥离线使用。第二个好处是方便部署和撤销,即如果证书出现问题,只需要撤销相应级别的证书,根证书依然安全。
  4. 根CA证书都是自签名,即用自己的公钥和私钥完成了签名的制作和验证。而证书链上的证书签名都是使用上一级证书的密钥对完成签名和验证的。
  5. 怎样获取根CA和多级CA的密钥对?它们是否可信?当然可信,因为这些厂商跟浏览器和操作系统都有合作,它们的公钥都默认装到了浏览器或者操作系统环境里。

5. 分解HTTPS连接建立过程

     我们知道任何的TCP协议在传输数据之前都要进行TCP三次握手,https也不例外。根据RFC 2818标准(译者注:RFC 2818为HTTP Over TLS-网络协议),浏览器自动通过连接了443端口来响应HTTPS请求。

 5.1 客户端请求

     TLS将全部的通信以不同方式包裹为“记录”。浏览器首先发起对服务器的问候,它表示了这是一个“握手”记录。在浏览器问候中,包含了Session-Id,可支持的密文族等数据。

(1)Session ID:

    如果出于某种原因,对话中断,就需要重新握手。为了避免重新握手而造成的访问效率低下,这时候引入了session ID的概念, session ID的思想很简单,就是每一次对话都有一个编号(session ID)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就可以重新使用已有的"对话密钥",而不必重新生成一把。Session ID是目前所有浏览器都支持的方法,但是它的缺点在于session ID往往只保留在一台服务器上。所以,如果客户端的请求发到另一台服务器,就无法恢复对话。session ticket就是为了解决这个问题而诞生的,目前只有Firefox和Chrome浏览器支持。后面关于https优化部分会着重介绍session ticket。

(2)密文族(Cipher Suites):

     密文族是浏览器所支持的加密算法的清单。RFC2246中建议了很多中组合,一般写法是"密钥交换算法-对称加密算法-哈希算法。以“TLS_RSA_WITH_AES_256_CBC_SHA”为例,TLS为协议,RSA为密钥交换的算法,AES_256_CBC是对称加密算法(其中256是密钥长度,CBC是分组方式),SHA是哈希的算法。浏览器支持的加密算法一般会比较多,而服务端会根据自身的业务情况选择比较适合的加密组合发给客户端。(比如综合安全性以及速度、性能等因素)

5.2 服务器回复

       服务器在收到client hello后,会回复三个数据包,下面分别看一下:
       1、我们得到了服务器的以Unix时间格式记录的UTC和28字节的随机数。
       2、Seesion ID,服务端对于session ID一般会有三种选择:
  • 恢复的session ID:我们之前在client hello里面已经提到,如果client hello里面的session ID在服务端有缓存,服务端会尝试恢复这个session;
  • 新的session ID:这里又分两种情况,第一种是client hello里面的session ID是空值,此时服务端会给客户端一个新的session ID,第二种是client hello里面的session ID此服务器并没有找到对应的缓存,此时也会回一个新的session ID给客户端;
  • NULL:服务端不希望此session被恢复,因此session ID为空。
       3、我们记得在client hello里面,客户端给出了21种加密族,而在我们所提供的21个加密族中,服务端挑选了“TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256”。这就意味着服务端会使用ECDHE-RSA算法进行密钥交换,通过AES_128_GCM对称加密算法来加密数据,利用SHA256哈希算法来确保数据完整性。这是百度综合了安全、性能、访问速度等多方面后选取的加密组合,具体后面的优化那篇会详细的介绍。

5.3 Certificate

    在前面的https原理研究中,我们知道为了安全的将公钥发给客户端,服务端会把公钥放入数字证书中并发给客户端(数字证书可以自签发,但是一般为了保证安全会有一个专门的CA机构签发),所以这个报文就是数字证书,4136byte就是证书的长度。

当服务器将以上的两个报文发给客户端后,这时发了一个server hello done的报文,意思是告诉客户端hello结束,并且不要求验证客户端的证书。(我们知道TLS协议中验证证书可以是双向的,即服务端也要验证客户端的身份来防止客户端的伪冒,但是这种场景在一般基于web的https中很少(通过U盾的网银是例外,U盾其实就是客户端证书,但这样也非常繁琐),因为基于web的应用客户数量大,很难为每个客户去提供相应的数字证书。但是对于一些企业之间的对接,出于安全考虑,很多情况下会采用双向认证的方式,因为对于两个企业来说也不存在client、server端的说法。)  

5.4 客户端验证证书

     之前的文章中说到,当客户端收到服务器发来的证书后会进行校验来确保证书是真实的服务器发来的,那么如何验证其真实性呢?主要靠的就是数字签名。algorithmIdentifier(签名的加密算法)为:SHA_RSA(注意这里的加密算法是证书中自带的,并非我们之间client、server里面的Cipher Suites中的算法,Cipher Suites中的算法只有密钥交换算法、对称数据加密算法、校验完整性的哈希算法,不包括相关签名的算法),而下方的encrypted部分就是数字签名,是由CA的私钥加密的,数字证书制作这块前面已经介绍过了,这里就不多说了。客户端收到数字证书中的数字签名后,由于证书的签名都是由上一级来完成的,因此会利用上一级证书提供的公钥进行解密,解密后得到签名值和自己再次哈希证书主题的值进行比对,如果两个值是一致的话,则认证通过。

5.5 密钥交换

     按照第四步客户端验证通过证书后,客户端将采用服务器给出的加密算法以及公钥将后面用于加密数据的对称密钥进行加密并发送给服务器。其实密钥交换这步远没有想象中的那么简单,主要有以下几个步骤(以下为RSA算法密钥交换的过程,百度用的密钥交换算法为ECDHE-RSA,比RSA更为复杂,这里就先介绍RSA算法):

1)客户端生成premaster_secret,首先对称密钥为了保证安全一定是随机密钥,一般的系统或者浏览器都会构建它自己的伪随机数发生器,之所以称之为伪随机数是因为真正意义上的随机数算法并不存在,这些函数还是利用大量的时变、量变参数来通过复杂的运算生成相对意义上的随机数,但是这些数之间还是存在统计学规律的,只是想要找到生成随机数的过程并不那么容易。在进行密钥交换的时候,客户端会利用server hello里面带的随机数2(client hello里面的随机数我们称为随机数1,这是为了方面后面master_secret)生成premaster_secret,premaster_secret长度为48个字节,前2个字节是协议版本号,剩下的46个字节填充随机数。

2)注意,对称加密不会直接用这个premaster_secret进行加密。因为这个premaster_secret完全由客户端来提供,完成没有服务端的相关信息的参与,因此客户端会利用premaster_secret生成master_secret,然后再用master_secret生成对称密钥算法、MAC 算法的密钥。

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

pre_master_secret就是我们之前传送的随机密码串,”mastersecret”是一串ASCII码,再加上之前提到的random1和random2。PRF是在规范中约定的伪随机函数,它将密钥、ASCII码标签、哈希值整合在一起。各有一半的参数分别使用MD5和SHA-1获取哈希值。这是一种十分明智的做法,即使是想要单单破解相对简单MD5和SHA-1也不是那么容易的事情。而且这个函数会将返回值传给自身直至迭代到我们需要的位数。关于PRF的具体细节问题

3)客户端得到master_secret后,根据协议约定,我们需要利用PRF生成这个会话中所需要的各种密钥,称之为“密钥块”(key block),密钥块用于构成以下密钥:

client_write_MAC_secret、server_write_MAC_secret (MAC 算法的密钥)
client_write_key、server_write_key (对称算法密钥or会话密钥)
client_write_IV、server _write_IV (初始化向量,运用于分组对称加密,如果mode是CBC则需要这个值,这个后面降到算法那篇会重点介绍)

以上的6个密钥都是通过PRF运算出来的,具体的运算方法比较复杂,后面讲到算法那张会单独介绍。

4)至此,经过前三步客户端已经完成了相关密钥的生成。此时客户端通过证书中的服务端的公钥将premaster_secret加密后发给客户端,通过RSA非对称密钥算法利用数字证书中获得的公钥将premaster加密发给服务端。


  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值