Skip to main content

https 获取加密秘钥的过程

https 加密机制#

1.1为什么需要加密#

因为http的内容是明文传输的,明文数据会经过中间代理服务器、路由器、wifi热点、 通信服务运营商等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了,他还可以篡改传输的信息且不被双方察觉,这就是中间人攻击。所以我们才需要对信息进行加密。最简单容易理解的就是对称加密。

1.2什么是对称加密#

就是有一个密钥,它可以对一段内容加密,加密后只能用它才能解密看到原本的内容,和我们日常生活中用的钥匙作用差不多。

1.3对称加密是否可以保证数据安全#

如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。

但是有个最大的问题,这个密钥怎么让传输的双方知晓,同时不被别人知道

如果由服务器生成个密钥并传输给浏览器, 那这个传输过程 中密钥被别人劫持弄到手了怎么办? 之后他就能用密 钥解开双方传输的任何内容了,所以这么做当然不行。

换种思路?试想一下, 如果浏览器内部就预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的,这样浏览器只要预存好世界上所有HTTPS网站的密钥就行啦!这么做显然不现实。

那如何解决?这就需要神奇的非对称加密?

1.4什么是非对称加密#

有两把密钥,通常把叫做公钥、 一把叫做私钥, 用公钥加密的内容必 须用私钥才能解开,同样,私钥加密的内容 只有公钥能解开。

1.5非对称加密可以保证数据安全吗?#

鉴于非对称加密的机制,我们可能会有这种思路:服务器先把公钥直接明文传输给浏览器,之后浏览器向服务器传数据前都先用这个公钥加密好再传,这条数据的安全似乎可以保障了!因为只有服务器有相应的私钥能解开这条数据。

然而由服务器到浏览器的这条路怎么保障安全?如果服务 器用它的的私钥加密数据传给浏览器,那么浏览器用公钥可以解密它,而这个公钥是一开始通过明文传输给浏览器的,这个公钥被谁劫持到的话,他也能用该公钥解密服务器传来的信息了。所以目前似乎只能保证由浏览器向服务器传输数据时的安全性

1.6改良的非对称加密方案#

我们已经理解通过-组公钥私钥,已经可以保证单个方向传输的安全性,那用两组公钥私钥,是不是就能保证双向传输都安全了?

  1. 某网站拥有用于非对称加密的公钥A、私钥AA;浏览器拥有用于非对称加密的公钥B、私钥BB。
  2. 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 浏览器把公钥B明文传输给服务器。
  4. 之后浏览器向服务器传输的所有东西都用公钥A加密,服务器收到后用私钥AA解密。由于只有服务器拥有这个私钥AA可以解密,所以能保证这条数据的安全。
  5. 服务器向浏览器传输的所有东西都用公钥B加密,浏览器收到后用私钥BB解密。由于只有浏览器拥有这个私钥BB可以解密,所以能保证这条数据的安全。

的确可以,但是Https并没有采取这种方案,其中最重要的原因是非对称加密算法非常耗时,特别是加密解密一些较大数据的时候有 些力不从心,而对称加密快很多。

1.7非对称加密+对称加密#

既然非对称加密耗时,非对称加密+对称加密结合可以吗?而且得尽量减少非对称加密的次数。当然是可以的,而且非对称加密、解密各只需用一次即可。

  1. 某网站拥有用于非对称加密的公钥A、私钥AA。
  2. 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
  4. 服务器拿到后用私钥AA解密得到密钥X。
  5. 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都用密钥X加密解密。

这样是不是就很完美了,Https就是 采用的这种方案。但是这样还是会存在漏洞。

1.8中间人攻击#

中间人的确无法得到浏览器生成的密钥X,这个密钥本身被公钥A加密了,只有服务器才有私钥AA解开拿到它!然而中间人却完全不需要拿到密钥AA就能干坏事。

  1. 某网站拥有 用于非对称加密的公钥A、私钥AA。
  2. 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
  3. 中间人劫持到公钥A, 保存下来,把数据包中的公钥A替换成自己伪造的公钥B (它当然也拥有公钥B对应的私钥BB)。
  4. 浏览器随机生成个用于 对称加密的密钥X,用公钥B (浏览器不知道公钥被替换 了)加密后传给服务 器。
  5. 中间人劫持后用私钥BB解密得到密钥X,再用公钥A加密后传给服务器。服务器拿到后用私钥AA解密得到密钥X。

这样在双方都不会发现异常的情况下,中间人得到了密钥X。根本原因是浏览器无法确认自己收到的公钥是不是网站自己的。

1.9如何证明浏览器收到的公钥定是该网站的公钥#

现实生活中,如果想证明某身份证号一定是小明的, 怎么办?看身份证。这里政府机构起到了“公信”的作用,身份证是由它颁发的,它本身的权威可以对一个人的身份信息作出证明。互联网中能不能搞这么个公信机构呢?给网站颁发个“ 身份证”?

1.10数字证书#

网站在使用HTTPS前,需要向“CA机构”申请颁发一份数字证书, 数字证书里有证书持有者、证书持有者的公钥等信息,服务器把证书传输给浏览器,浏览器从证书里取公钥就行了,证书就如身份证一样,可以证明“该公钥对应该网站”。然而这里又有-个显而易见的问题了,证书本身的传输过程中,如何防止被篡改?即如何证明证书本身的真实性?身份证有些防伪技术, 数字证书也有对应的防伪措施。

1. 11如何放防止数字证书被篡改?#

我们把证书内容生成一份“ 签名”,比对证书内容和签名是否一致就能察 觉是否被篡改。这种技术就叫数字签名。 数字签名有两种功效:

  • 能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。
  • 数字签名能确定消息的完整性,证明数据是否未被篡改过。

https 获取加密秘钥的过程#

经过上边的分析,现在再来理解就比较容易理解了。

  • 首先,客户端发起握手请求,以明文传输请求信息,包含版本信息,加密-套件候选列表,压缩算法候选列表,随机数,扩展字段等信息(这个没什么好说的,就是用户在浏览器里输入一个HTTPS网址, 然后连接到服务端的443端口。
  • 服务端的配置,采用HTTPS协议的服务器必须要有套数字证书, 可以自己制作, 也可以向组织申请。区别就是自己颁发 的证书需要客户端验证通过, 才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。 如果对公钥不太理解,可以想象成一 把钥匙和一个锁头, 只是世界上只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。
  • 服务端返回协商的信息结果,包括选择使用的协议版本version,选择的加密套件cipher suite, 选择的压缩算法compression method、 随机数random_ S以及证书。(这个证书其实就是公明,只是包含了很多信息,如证书的颁发机构,过期时间等等。)
  • 客户端验证证书的合法性,包括可信性,是否吊销,过期时间和域名。(这部分工作是由客户端的SSL/TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警示框,提示证书存在的问题。如果证书没有问题,那么就生成一个随机值。然后用证书(也就是公钥)对这个随机值进行加密。就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。)
  • 客户端使用公匙对对称密匙加密,发送给服务端。(这部分传送的是用证书加密后的随机值,目的是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密 了。)
  • 服务器用私钥解密,拿到对称加密的密匙。(服务端用私钥解密后,得到了客户端传过来的随机值,然后把内容通过该随机值进行对称加密,将信息和私钥通过某种算法混合在一起, 这样除非知道私 钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。)
  • 传输加密后的信息,这部分信息就是服务端用私钥加密后的信息,可以在客户端用随机值解密还原。
  • 客户端解密信息,客户端用之前生产的私钥解密服务端传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策。

HTTPS必须在每次请求中都要先在SSL /TL S层进行握手传输密钥吗?#

如果每次https的请求都需 要进行TL S的握手,TLS的握手那么复杂,势必会对通信带来较大的延时,这对注重用户体验的网站来说, 是不可接受的。那么有什么办法可以避免这种情况吗?

其实是通过一个Session Identifier (会话标识符),该Session ID是TLS握手中生成的Session ID。 服务端可以将Session ID协商后的信息存起来,浏览器也可以保存Session ID, 并在后续的Client Hello 握手中带上它,如果服务端能找到与之匹配的信息,就可以完成一 次快速握手。