代码改变世界

SSL 杂谈

2019-12-04 02:44  陈心朔  阅读(511)  评论(0编辑  收藏  举报

在电子邮件系统中的开发和维护中,由于安全性的需要,经常会遇到 SSL 相关的问题,这里整理下 SSL 的一些基础知识

什么是 SSL

SSL (Secure Sockets Layer) 是一种在应用层和传输层之间的协议,对传输层(TCP)到应用层(HTTP)的数据进行加密,主要是为了保证 Internet 上数据传输的安全性,确保数据在传输过程中不被截取或监听

SSL 在技术上位与应用层,但从开发者的角度来看,它是一个提供 TCP 服务的传输层协议

TLS(Transport Layer Security)是 SSL 的继任者,在很多场合还是用 SSL 来指代 SSL/TLS

基本大部分支持 SSL 加密数据的服务器,都是采用 OpenSSL 库来实现的

OpenSSL是一个强大的安全套接字层密码库,Apache使用它加密HTTPS,OpenSSH使用它加密SSH,它还是一个多用途的、跨平台的密码工具

SSL 协议的安全机制

SSL 通过以下三种机制,实现了网络通信的安全性

1. 数据传输的机密性
通过对称/非对称加密算法,在通信双方之间建立加密通道,保证数据传输的机密性
2. 身份验证机制
使用数字签名来验证通信对端的身份
3. 消息完整性验证
基于 md5/sha 等 hash 算法来保证消息的完整性,避免网络中传输的数据被非法篡改

SSL 的工作原理

简单了解下网络通信加密的发展过程,假设 A 和 B 之间需要网络通信

远古

远古时期民风淳朴,路不拾遗、夜不闭户,A 要发数据给 B,直接发就好,根本用不担心数据会被窃听和篡改

上古

上古时期出现了这样一类人 C,C 不但窃听 A 和 B 之间的网络数据,还会拦截 A 与 B 之间的信息,然后伪造后再发会给 A/B,C 就是中间人攻击(Man In The Middle Attack)

为了应对 C 的攻击,A 和 B 开始对自己的数据进行加密

A 和 B 会使用一个共享的密钥,A 在发送数据之前使用这个密钥加密,B 在收到数据之后,会用这个密钥进行解密
由于加解密使用的是同一个密钥,所以这类加密算法被称为对称加密算法

对称加密算法

在 1981 年,DES(Data Encryption Standard)被提出,这是一种对称加密算法
DES 使用一个 56 bit 的密钥来完成数据的加解密,尽管看起来有点短,但是在上古时代 56 bit 已经够用了

但是又引发了一个新的问题,A 和 B 需要共享一个 56 bit 的密钥,并且这个密钥需要保持私密,否则让 C 拿到这个密钥就失去了加密的意义
首先 A 和 B 不能通过网络来传递密钥,在密钥确定前所有的通信都是不安全的,密钥有可能被 C 拦截;A 和 B 必须见面约定好密钥,如果因为任何原因该密钥泄漏了,A 和 B 必须再重新见面约定一个新的密钥

现在 A B 之间,只要保证了密钥的安全,那么整个网络通信就是安全的

中古

随着技术的发展,计算机速度变的越来越快,快到可以通过暴力破解的方法来解密经过 DES 加密的信息
在上古时代,破解 56 bit 密钥需要的时间非常长,而在中古时代可能只需要几天就可以破解 56 bit 的密钥

为了应对这个情况提出了新的协议,例如 AES(Advanced Encryption Standard)将使用 256 bit 的密钥来进行加解密,至少在可预见的将来,计算机无法在有限的时间内来破解这个密钥
所以在中古时代,主要应用将对称加密算法的密钥长度变长,来应对中间人攻击;A 和 B 仍需要见面约定一个密钥

现代

到了现代,网络通信十分发达,A 不止和 B 通信,还同时和 N 个人进行网络通信,A 不可能跑去和每个人都见面商量一个密钥

所以一种新的加密算法被提出,就是非对称加密算法
非对称加密算法使用两个密钥,一个 Public Key 和一个 Private Key,通过特殊的算法来实现加解密使用不同的密钥,所以称为非对称加密算法

非对称加密算法

非对称加密算法最著名的是 RSA 算法,其中 Public Key 和 Private Key 是数学相关的,但是现有的算法无法从一个密钥来推导出另一个密钥

非对称加解密流程:

  1. A 和 B 在本地生成配对的 Public Key 和 Private Key,保留 Private Key 并通过网络交换 Public Key
  2. 假设 A 要给 B 发送数据,A 先把数据经过 Hash 处理后生成摘要信息 Digest 1,并使用自己的 Private Key 加密数据的 Digest 生成数字签名
  3. 然后再用 B 的 Public Key 加密数据本身,A 将数字签名和加密后的数据,再加上一些其他信息( 如 nonce 等 注1 )通过网络发送给 B
  4. B 收到数据后,使用 A 的 Public Key 解密数字签名,如果能成功解密获取 Digest 1,则说明该数据是 A 发来的
  5. B 使用自己的 Private Key 解密数据后,做同样的 Hash 处理生成 Digest 2,与 Digest 1 对比;
    如果两者相等,表示数据没有被篡改,否则该数据则被视为无效丢弃

非对称加密算法的优点在于,A 可以保留 Private Key,通过网络传递 Public Key;即使 Public Key 被 C 拦截了,因为没有 Private Key,C 还是没有办法完成信息的破解
既然不怕 C 知道 Public Key,那么 A 和 B 通信不需要再见面商量密钥,直接通过网络传递 Public Key 即可
并且通过数字签名,可以确保数据来源的安全性,且不会被篡改

非对称加密的安全隐患

按照非对称加密的方案,在 A 与 B 通信的最开始,需要通过网络交换 Public Key,但是如果 C 在中间拦截了呢?
假设有这种情况:

  1. 当 A 给 B 发消息,A 生成数字签名后,使用 C 传来的 Public Key (Fake) 加密了数据
  2. C 拦截了数据包,使用 C 的 Private Key 解密,得到原始数据
  3. C 使用自己的 Private Key 生成数字签名,再用 B 的 Public Key 加密数据,发送给 B
  4. B 收到数据后,使用 C 的 Public Key (Fake) 解密数字签名,对比 Digest 后发现匹配,以为该数据是 A 发来的,中间人攻击仍可能存在

这一下又回到了上古时代,为了保证 Public Key 不被拦截,A 和 B 仍需要见面交换 Public Key
但是和上古时代不一样,见面的实质已经变了
在上古时代,见面是为了商量一个密钥,密钥的内容很重要,不能泄露;而在现代,见面是为了确认 Public Key 的真实性,Public Key 的内容是可以公开的

那么如果有其他方法能保证 Public Key 的真实性,A 和 B 是可以不用见面的

CA

现实中,通过 CA(Certificate Authority)来保证 Public Key 的真实性

CA 在数字世界里是一个权威的机构,CA 签发证书是很严肃的,它有一系列手段来检查申请签发的是不是某个人(或机构 / 组织 / 企业)

一个网站有了 CA 签发的证书

A/B 会把自己的 Public Key 交给 CA,CA 用自己的 Private Key 加密,加密完成的数据称为数字证书
现在 A 要给 B 传递 Public Key,B 传递的是 CA 加密后的数字证书;A 收到以后,会通过 CA 颁发的 CA 证书(包含了 CA 的 Public Key)来解密 B 的数字证书,从而安全的得到 B 的 Public Key

那么如何确保 CA 证书不被劫持呢?中间人 C 可以把一个假的 CA 证书发给 B,从而欺骗 B ?
不存在的,CA 把自己的 CA 证书集成在了浏览器和操作系统里面,当 B 使用浏览器或者操作系统的时候,已经获得了 CA 证书,不必再从网络获取,自然不存在劫持的问题

现在 A 和 B 都有了 CA 证书,在交换 Public Key 的阶段,直接交换彼此的数字证书即可
中间人 C 可以拦截 A 和 B 的数字证书,也可以通过 CA 证书解密获得 A 和 B 的 Public Key,但是 C 因为 C 不在 CA 体系中,没有 CA 的 Private Key,无法伪造出一个可以通过 CA 认证的数字证书,A 和 B 自然也不会相信伪造的证书
所以采用 CA 认证后,A 和 B 的 Public Key 真实性得到了保证,A 和 B 可以通过网络来交换 Public Key(实际上是被 CA 加密后的数字证书)

实际使用

由于非对称加密算法比对称加密码算法复杂的多,在网络通信中的开销自然很大,所以在实际使用中,使用非对称加密算法只做一件事,就是传递对称加密算法的密钥
密钥确定后,A 和 B 就可以通过对称加密进行网络通信,既不影响效率,又保证了安全

所以在现代,A 和 B 之间需要网络通信需要经过以下几个步骤:

  1. 通过 CA 体系交换 Public Key
  2. 通过非对称加密算法交换对称加密密钥
  3. 使用对称加密的密钥进行网络通信

SSL 的应用

SSL 最广泛的应用应该是 HTTPS(HTTP over SSL) 了,通过在 HTTP 下加入 SSL 层,实现安全的 HTTP 通道

前面提到 CA 作为公证机构,能确保数字证书的真实性,但在实际应用中,CA 认证是需要收费的,一般只有大的公司、机构(如电商、银行、金融机构等)才会去做 CA 认证,普通用户则不会有 CA 认证,而伪造 CA 证书的难度是非常高的

在用户与服务端的通信中,服务端可以通过 CA 授予的数字证书自证身份,而用户的身份验证一般是通过用户名/密码来确认身份,对于安全性要求高的(如网银平台)则可以通过手机号 / 身份证的验证,来进一步确保用户发来的请求是本人操作

个人数字证书

当我们在淘宝购物的时候,使用支付宝支付,会提示你需要安装支付宝用户的个人数字证书,证明你是该账户的拥有者

那为什么像支付宝这类的企业可以给用户安装数字证书呢?因为它用的是自签发的方式,也就是说,这个 CA 它自己做了

只要淘宝网认可支付宝的地位,那么你在淘宝就可以使用支付宝自签发的证书,对于支付宝进一步保证了用户账户的安全性

当然,支付宝所担负的风险也是很大的,任何一家 CA 都有一个根证书,数字证书的防伪则需要依靠其根证书(或其签发的下级证书)来签名;而 CA 机构对于根证书的保护(实际上是保护证书里公钥对应的私钥)措施是相当严密的,做到这个的成本也相当高,那么支付宝作为 CA 就要面对证书泄漏的风险

所以在设备上安装个人支付宝数字证书要谨慎,尽量在个人使用的电脑上安装

其他

注一 :NONCE 属性的作用

Nonce,Number used once 或 Number once 的缩写,在密码学中 Nonce 是一个只被使用一次的任意或非重复的随机数值,在各类验证协议的通信应用中确保验证信息不被重复使用以对抗重放攻击(Replay Attack)

重放攻击是指,hacker 将截取的数据包,直接发送给服务端,从而达到复制请求的结果
例:用户发送了一条获取收件箱邮件的请求,该请求中有用户加密后的密码作为验证;hacker 截取了这条请求,虽然获取不到加密后的密码原文,但是可以将该请求原封不动的发送给服务端,服务端收到请求后验证有效,将用户的邮件返回给 hacker,从而成功的盗取信息

nonce 是防御重放攻击的一种手段,服务器在客户端第一次请求时,生成一个随机数 nonce 返回给客户端,客户端使用 nonce 和密码混合进行非可逆加密(md5、sha1 等)再发送请求给服务端,服务端进行同样的加密后对密码进行验证
每个 nonce 只能供一个用户使用一次,即使 hacker 将该请求重新发送给服务端,服务端检查到是一个重复的 nonce,则该请求可能是恶意的

参考

浅谈SSL/TLS工作原理

数字签名、数字证书、SSL、https是什么关系?

SSL技术白皮书

Perfect Forward Secrecy. What it is?