未济,亨。小狐汔济,濡其尾,无攸利。——《易》

六、密钥管理

当不再担心身份会被冒充、篡改之后,我们再来详细谈谈网络通信中对于加密算法的密钥管理。

在密钥被签发后,密钥管理一般有三个步骤:交换存储使用。其中最重要也是最难的点在于密钥交换

密钥交换

进行安全通信之前,各用户间需要确立加密程序的细节,尤其是密钥。在对称密钥加密系统,各用户间需要确立共同使用的单一密钥,此步骤即密钥交换。

前面章节已经提过,交换对称密钥必须透过另一安全的通信管道进行;否则,如果以明文形式在网络发送,将使窃听者能够立即得知密钥以及据其加密的数据。以前,交换密称密钥是非常麻烦的,可能需要使外交邮袋等安全渠道。

公开密钥加密的出现大大减轻了交换对称密钥的困难,公钥可以公开(透过不安全、可被窃听的渠道)发送,用以加密明文。不过,公钥加密在在计算上相当复杂,性能欠佳、远远不比对称加密。

因此,在一般实际情况下,往往通过公钥加密来随机创建临时的对称秘钥,亦即对话键,然后才通过对称加密来传输大量、主体的数据。(也叫混合加密算法)

密钥交换/协商机制的几种类型

1.依靠非对称加密算法

  • 原理:

拿到公钥的一方先生成随机的会话密钥,然后利用公钥加密它;再把加密结果发给对方,对方用私钥解密;于是双方都得到了会话密钥。

  • 举例:

RSA

2. 依靠专门的密钥交换算法

  • 原理:

这个原理比较复杂,一两句话说不清楚,待会儿聊到 DH 的那个章节会详谈。

  • 举例:

DH 算法及其变种(ECDH算法

3. 依靠通讯双方事先已经共享的“秘密”

  • 原理:

既然双方已经有共享的秘密(这个“秘密”可能已经是一个密钥,也可能只是某个密码/password),只需要根据某种生成算法,就可以让双方产生相同的密钥(并且密钥长度可以任意指定)

  • 举例:

PSKSRP

基于 RSA 的密钥协商

概述

这大概是 SSL 最古老的密钥协商方式——早期的 SSLv2 只支持一种密钥协商机制,就是它。(前一篇)介绍身份认证重要性的时候,也是拿 RSA 来演示。

RSA 是一种【非】对称加密算法。特点是:加密和解密用使用【不同的】密钥。

并且“非对称加密算法”既可以用来做“加密/解密”,还可以用来做“数字签名”。

密钥协商的步骤

  1. 客户端连上服务端
  2. 服务端发送 CA 证书给客户端
  3. 客户端验证该证书的可靠性
  4. 客户端从 CA 证书中取出公钥
  5. 客户端生成一个随机密钥 k,并用这个公钥加密得到 k'
  6. 客户端把 k' 发送给服务端
  7. 服务端收到 k' 后用自己的私钥解密得到 k
  8. 此时双方都得到了密钥 k,协商完成

如何防范偷窥(嗅探)

  • 攻击方式1
攻击者虽然可以监视网络流量并拿到公钥,但是【无法】通过公钥推算出私钥(这点由 RSA 算法保证)
  • 攻击方式2
攻击者虽然可以监视网络流量并拿到 k',但是攻击者没有私钥,【无法解密】 k',因此也就无法得到 k

如何防范篡改(假冒身份)

  • 攻击方式1
如果攻击者在第2步篡改数据,伪造了证书,那么客户端在第3步会发现(这点由证书体系保证)
  • 攻击方式2
如果攻击者在第6步篡改数据,伪造了k',那么服务端收到假的k'之后,解密会失败(这点由 RSA 算法保证)。服务端就知道被攻击了。

基于 DH 的密钥协商

概述

DH 算法又称“Diffie–Hellman 算法”。这是两位数学牛人的名称,他们创立了这个算法。该算法用来实现【安全的】“密钥交换”。它可以做到——“通讯双方在完全没有对方任何预先信息的条件下通过不安全信道创建起一个密钥”。这句话比较绕口,通俗地说,可以归结为两个优点:

  1. 通讯双方事先【不】需要有共享的秘密。
  2. 用该算法协商密码,即使协商过程中被别人全程偷窥(比如“网络嗅探”),偷窥者也【无法】知道协商得出的密钥是啥。

但是 DH 算法本身也有缺点——它不支持认证。

也就是说:它虽然可以对抗“偷窥”,却无法对抗“篡改”,自然也就无法对抗“中间人攻击/MITM”(前一篇已经强调过——缺乏身份认证,【必定会】遭到“中间人攻击/MITM”)。

为了避免遭遇 MITM 攻击,DH 需要与其它签名算法(比如 RSA、DSA、ECDSA)配合——靠签名算法帮忙来进行身份认证。当 DH 与 RSA 配合使用,称之为“DH-RSA”,与 DSA 配合则称为“DH-DSA”,以此类推。

反之,如果 DH 【没有】配合某种签名算法,则称为“DH-ANON”(ANON 是“anonymous”(匿名)的简写)。此时会遭遇“中间人攻击/MITM”。

关于该算法具体数学原理,可以参见迪菲-赫尔曼密钥交换

密钥协商的步骤

  1. 客户端先连上服务端
  2. 服务端生成一个随机数 s 作为自己的私钥,然后根据算法参数计算出公钥 S(算法参数通常是固定的)
  3. 服务端使用某种签名算法把“算法参数(模数p,基数g)和服务端公钥S”作为一个整体进行签名
  4. 服务端把“算法参数(模数p,基数g)、服务端公钥S、签名”发送给客户端
  5. 客户端收到后验证签名是否有效
  6. 客户端生成一个随机数 c 作为自己的私钥,然后根据算法参数计算出公钥 C
  7. 客户端把 C 发送给服务端
  8. 客户端和服务端(根据上述 DH 算法)各自计算出 k 作为会话密钥

如何防范偷窥(嗅探)

嗅探者可以通过监视网络传输,得到算法参数(模数p,基数g)以及双方的公钥,但是【无法】推算出双方的私钥,也【无法】推算出会话密钥(这是由 DH 算法在数学上保证的)

如何防范篡改(假冒身份)

  • 攻击方式1
攻击者可以第4步篡改数据(修改算法参数或服务端公钥)。但因为这些信息已经进行过数字签名。篡改之后会被客户端发现。
  • 攻击方式2
攻击者可以在第7步篡改客户端公钥。这步没有签名,服务端收到数据后不会发现被篡改。但是,攻击者篡改之后会导致“服务端与客户端生成的会话密钥【不一致】”。在后续的通讯步骤中会发现这点,并导致通讯终止。
(协议初始化/握手阶段的末尾,双方都会向对方发送一段“验证性的密文”,这段密文用各自的会话密钥进行【对称】加密,如果双方的会话密钥不一致,这一步就会失败,进而导致握手失败,连接终止)

基于 PSK 的密钥协商

概述

PSK 是“Pre-Shared Key”的缩写。顾名思义,就是【预先】让通讯双方共享一些密钥(通常是【对称加密】的密钥)。所谓的【预先】,就是说,这些密钥在 TLS 连接尚未建立之前,就已经部署在通讯双方的系统内了。

这种算法用的不多,它的好处是:

  1. 不需要依赖公钥体系,不需要部属 CA 证书。
  2. 不需要涉及非对称加密,TLS 协议握手(初始化)时的性能好于前述的 RSA 和 DH。 更多介绍可以参见维基百科,链接在“这里”。

密钥协商的步骤

(由于 PSK 用的不多,下面只简单介绍一下步骤,让大伙儿明白其原理)

  • 在通讯【之前】,通讯双方已经预先部署了若干个共享的密钥。
  • 为了标识多个密钥,给每一个密钥定义一个唯一的 ID
  • 协商的过程很简单:客户端把自己选好的密钥的 ID 告诉服务端。
  • 如果服务端在自己的密钥池子中找到这个 ID,就用对应的密钥与客户端通讯;否则就报错并中断连接。

如何防范偷窥(嗅探)

使用这种算法,在协商密钥的过程中交换的是密钥的标识(ID)而【不是】密钥本身。 就算攻击者监视了全过程,也无法知晓密钥是什么。

如何防范篡改(假冒身份)

PSK 可以单独使用,也可以搭配签名算法一起使用。

  • 对于单独使用:
如果攻击者篡改了协商过程中传送的密钥 ID,要么服务端发现 ID 无效(协商失败),要么服务端得到的 ID 与客户端不一致,在后续的通讯步骤中也会发现,并导致通讯终止。
(协议初始化/握手阶段的末尾,双方都会向对方发送一段“验证性的密文”,这段密文用各自的会话密钥进行【对称】加密,如果双方的会话密钥不一致,这一步就会失败,进而导致握手失败,连接终止)
  • 对于搭配签名算法
如果攻击者篡改了协商过程中传送的密钥 ID,验证签名会失败

补充说明

PSK 与 RSA 具有某种相似性——既可以用来搞“密钥协商”,也可以用来搞“身份认证”。 所以,PSK 可以跟 DH(及其变种)进行组合。例如:DHE-PSK、ECDHE-PSK

基于 SRP 的密钥协商

概述

SRP 是“Secure Remote Password”的缩写。

这个算法有点类似于刚才提到的 PSK——只不过 client/server 双方共享的是比较人性化的密码(password)而不是密钥(key)。该算法采用了一些机制(盐/salt、随机数)来防范“嗅探/sniffer”或“字典猜解攻击”或“重放攻击”。

这个算法应该用得很少——OpenSSL 直到2012年才开始支持该算法。所以这里就不展开了,有兴趣的同学可以去看 RFC2945 的协议描述

密钥存储

对称加密使用的单一密钥会被收发双方存储,公开密钥加密的私钥由于还有数字签名的功能,所以都必须安全存储,以保障通信安全。业界已发展出各种各样的技术来保障密钥得到妥善存储,包括定期或不定的系统检测是否有入侵之虞、对存储媒体或服务器提供高强度的物理防护及监控。

最常见的是加密应用程序负责管理用户的密钥,使用密钥时则需要输入认别用户的访问密码。对于认证机构,一旦私钥外泄,将可能导致整个信任链被摧毁,影响广及众多客户,所以认证机构会使用硬件安全模块,有些存储私钥的计算机甚至平时不会连线,只在固定的调度下,经过一系列严谨的行政程序重重把关,才会取出私钥为客户签名证书。

在信任链设计中,绝大部分的根证书都不会直接为客户签名,而是先签名一个(或多个)中继证书,再由中继证书为客户签名,这可以加强控管能力及控制一旦签名私钥被泄时的损失。

密钥使用

密钥的有效期限是一个重要问题,一个密钥应该在产生后多久被汰换呢?

密钥汰换之后,旧有的密钥就无法再解密新产生的密文,丧失对窃听者的价值,这会增加了攻击者所需要投入的气力,所以密钥应该经常替换。

同时,这也可以减低信息一旦被破解(_一般是回溯性破解【注1】_)时的损失:因为窃听者可能在破解密钥之前一直存储截取到的加密消息,等待成功破解密钥的一刻。所以密钥更换得越频密,窃听者可解读的消息就越少。

在过去,如果可靠的密钥交换程序非常困难或者仅仅间歇可行,对称密钥会被长期使用。

但在理想情况下,对称密钥应该在每次交换消息或会话时转换(_完美正向加密【注2】_),使得如果某一密钥被泄(例如,被盗窃,密码分析或社会工程化)时,只有单一消息或会话被解读。

基于公开密钥加密的特性,一对公钥和私钥的有效期一般会长于对称加密所使用的单一密钥,尤其是需要认证机构签核的电子证书,当中涉及行政及部署成本,所以可能是三个月至一、两年不等,考虑的因素包括配合加密算法的密钥长度、存储私钥的强度、一旦外泄可能引致的风险、更换程序对运行中的服务的影响、以及运行成本。

七、TSL握手

有了前面的基础知识,这章我们就来讨论下TSL完整的实现过程。

TSL建立连接要经过四次握手, 握手过程又分为:

  1. 单向验证:就是server端将证书发送给客户端,客户端验证server端证书的合法性等。例如百度、新浪、google等普通的https网站。
  2. 双向验证:不仅客户端会验证server端的合法性,同时server端也会验证客户端的合法性。例如银行网银登陆,支付宝登陆交易等。

下面只讨论单向验证的情况:

第一步:客户端发出请求(ClientHello)

首先,客户端(通常是浏览器)先向服务器发出加密通信的请求,这被叫做ClientHello请求。

在这一步,客户端主要向服务器提供以下信息。

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

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

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

第二步:服务器回应(SeverHello)

服务器收到客户端请求后,向客户端发出回应,这叫做SeverHello。服务器的回应包含以下内容。

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

除了上面这些信息,如果服务器需要确认客户端的身份,就会再包含一项请求,要求客户端提供"客户端证书"。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。

第三步:客户端回应

客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。

如果证书没有问题,客户端就会从证书中取出服务器的公钥。然后,向服务器发送下面三项信息。

(1) 一个随机数。该随机数用服务器公钥加密,防止被窃听。
(2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
(3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。

上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话密钥"。

至于为什么一定要用三个随机数,来生成"会话密钥",dog250解释得很好:

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

此外,如果前一步,服务器要求客户端证书,客户端会在这一步发送证书及相关信息。

第四步: 服务器的最后回应

服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"。然后,向客户端最后发送下面信息。

(1)编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。

至此,整个握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的HTTP协议,只不过用"会话密钥"加密内容。

握手过程拟人化说明

A:我想和你安全的通话,我这里的对称加密算法有DES,RC5, 密钥交换算法有RSA和DH, 摘要算法有MD5和SHA。
B:我们用DES-RSA-SHA这对组合好了。 这是我的证书,里面有我的名字和公钥,你拿去验证一下我的身份(把证书发给A)。 目前没有别的可说的了。
A:(查看证书上B的名字是否无误,并通过手头早已有的CA的证书验证了B的证书的真实性,如果其中一项有误,发出警告并断开连接,这一步保证了B的公钥的真实性)
(产生一份秘密消息,这份秘密消息处理后将用作加密密钥,加密初始化向量(IV)和hmac的密钥。将这份秘密消息-协议中称为per_master_secret-用B的公钥加密,封装成称作ClientKeyExchange的消息。由于用了B的公钥,保证了第三方无法窃听)
我生成了一份秘密消息,并用你的公钥加密了,给你(把ClientKeyExchange发给B) 注意,下面我就要用加密的办法给你发消息了!
(将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥) [我说完了]
B:(用自己的私钥将ClientKeyExchange中的秘密消息解密出来,然后将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥,这时双方已经安全的协商出一套加密办法了) 注意,我也要开始用加密的办法给你发消息了! [我说完了]

八、其他

HTTP与HTTPS区别小结:

  1. HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
  2. HTTP 是不安全的,而 HTTPS 是安全的
  3. HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
  4. 在OSI 网络模型中,HTTP工作于应用层,而HTTPS 工作在传输层
  5. HTTP 无加密,而HTTPS 对传输的数据进行加密
  6. HTTP无需证书,而HTTPS 需要CA机构颁发的SSL证书

握手过程优化

对于HTTP,为了避免每次请求都要经过tcp三次握手,使用了长连接技术进行优化。

而对于HTTPS,如果每次重连都要重新TSL握手也是比较消耗性能和费时的,大致有几个优化方向:

  1. Session id及session ticket的复用,缩减证书交换时间,减少可能的计算以及RTT时间 。
  2. 选取相对来说计算量较小且安全的算法 。
  3. 将最消耗性能和费时的握手部分,交给加速卡承担。

在此不再详细展开,有兴趣的可以参考TLS 握手优化详解

回顾前篇请点击以下链接:

UCloud云计算:没那么浅地谈谈HTTP与HTTPS【一】​zhuanlan.zhihu.com图标UCloud云计算:没那么浅地谈谈HTTP与HTTPS【二】​zhuanlan.zhihu.com图标

参考链接:

  1. 浅谈HTTPS(SSL/TLS)原理
  2. SSL/TLS协议运行机制的概述
  3. HTTPS证书生成原理和部署细节
  4. 扫盲 HTTPS 和 SSL/TLS 协议系列
  5. 数字证书及 CA 的扫盲介绍
  6. RFC:The Transport Layer Security (TLS) Protocol Version 1.2
  7. HTTPS协议详解(三):PKI 体系
  8. 《HTTP权威指南》 人民邮电出版社 2012

本文作者:UCloud后台研发工程师 Hughes.Chen

博客地址:https://ulyc.github.io/


UCloud云计算
63 声望25 粉丝

国内顶尖的公有云服务商,秉持 “中立、专注”的态度,依托位于国内、亚太、北美、欧洲的全球17大数据中心以及北、上、广、深、杭等全国11地线下服务站,为近5万余家企业级客户提供云计算服务,间接服务用户数量超1...