SSL 到底是如何工作的?

SSL 是如何工作的?

证书安装在客户端(或浏览器?)和服务器(或 Web 服务器?)的什么地方?

当您将 URL 输入到浏览器并从服务器获取页面时,信任/加密/身份验证过程如何开始?

HTTPS 协议如何识别证书?当证书完成所有的信任/加密/身份验证工作时,HTTP 为什么不能与证书一起工作?

61032 次浏览

注意: 我最初的答案写得很匆忙,但是从那以后,这个问题变成了一个相当受欢迎的问题/答案,所以我把它扩展了一点,使它更加精确。

TLS 能力

“ SSL”是最常用来指代这个协议的名称,但是 SSL 特指90年代中期由 Netscape 设计的专有协议。“ TLS”是一个基于 SSL 的 IETF 标准,因此我将在回答中使用 TLS。这些天,几乎所有的网络安全连接都使用 TLS,而不是 SSL。

TLS 有以下几个功能:

  1. 加密应用程序层数据(在本例中,应用程序层协议是 HTTP)
  2. 向客户端验证服务器。
  3. 向服务器验证客户端。

第一和第二很常见。第三点就不那么常见了。你似乎只关注第二点,我来解释一下。

认证

服务器使用证书向客户端验证自己。证书是包含有关网站信息的一组数据[1] :

  • 域名
  • 公开密钥
  • 它的所有者
  • 发行的时候
  • 当它过期的时候
  • 谁发的
  • 等等。

您可以通过使用证书中包含的公钥来加密只能由相应的私钥解密的消息,从而实现机密性(上面的 # 1) ,私钥应该安全地存储在该服务器上。[2]我们把这个密钥对称为 KP1,这样以后就不会混淆了。您还可以验证证书上的域名是否与您正在访问的站点匹配(上面的 # 2)。

但是,如果一个对手可以修改发送到服务器和从服务器发送的数据包,如果该对手修改了您看到的证书并插入了他们自己的公钥或更改了任何其他重要细节,又会怎样呢?如果发生这种情况,对手可以拦截和修改任何您认为是安全加密的消息。

为了防止这种攻击,证书由其他人的私钥加密签名,以便任何拥有相应公钥的人都可以验证签名。让我们将这个密钥对称为 KP2,以明确这些密钥与服务器使用的密钥不同。

证书机关

那么是谁创建了 KP2? 谁签署了证书?

简单地说,证书认可机构创建 KP2,并且出售使用其私钥为其他组织签署证书的服务。例如,我创建一个证书,然后付钱给 Verisign 这样的公司,让他们用自己的私钥签署它。[3]因为除了 Verisign 没有人能够使用这把私人钥匙,所以没有人能够伪造这个签名。

我要怎么亲自拿到 KP2的公钥来验证签名呢?

我们已经看到证书可以保存公钥,计算机科学家也喜欢递归,那么为什么不把 KP2公钥放到证书中并以这种方式分发呢?一开始这听起来有点疯狂,但事实上它就是这样工作的。继续使用 Verisign 示例,Verisign 生成一个证书,其中包含关于它们是谁、允许它们签名的事物类型(其他证书)以及它们的公钥的信息。

现在,如果我有 Verisign 证书的副本,我可以使用它来验证我想访问的网站的服务器证书上的签名。很简单,对吧!

别这么快下结论。我必须从 某个地方拿到 Verisign 证书。如果有人伪造了 Verisign 证书并在其中放入了自己的公钥怎么办?然后他们就可以伪造服务器证书上的签名我们又回到了起点中间人攻击。

证书链

继续递归思考,我们当然可以引入第三个证书和第三个密钥对(KP3) ,并使用它来签署 Verisign 证书。我们称之为证书链: 链中的每个证书都用于验证下一个证书。希望您已经看到,这种递归方法从头到尾都是 Turtle/证书。什么时候才是个头?

因为我们不能创建无限数量的证书,所以证书链显然必须停止 某个地方,这是通过在链中包含一个证书即 自签的来完成的。

我暂停一会儿,让你从爆炸的脑袋里捡起脑浆碎片

是的,在证书链的末尾(也称为“ root”) ,将有一个证书使用它自己的密钥对来对自己进行签名。这消除了无限递归问题,但是并没有解决身份验证问题。任何人都可以创建一个自签的证书,上面写着任何东西,就像我可以创建一个假的普林斯顿文凭,上面写着我主修政治学,理论物理学,应用踢屁股,然后在下面签上我自己的名字。

这个问题的[有点乏味]解决方案只是挑选一组您显式信任的自签名证书。例如,我可能会说,“ I信任这个 Verisign 自签名证书。”

有了明确的信任,现在我可以验证整个证书链了。不管链中有多少证书,我都可以一直验证每个签名,直到根。当我到达根目录时,我可以检查这个根证书是否是我明确信任的。如果是这样,那我可以相信整个链条。

授权信托

TLS 中的身份验证使用 授予信任系统。如果我想雇一个汽车修理工,我可能不会相信任何随便找到的修理工。但也许我的朋友为某个机械师担保。既然我相信我的朋友,那我就可以相信那个机械师。

当您购买计算机或下载浏览器时,它会附带几百个它显式信任的根证书。[4]拥有和经营这些证书的公司可以通过签署其证书将这种信任授予其他组织。

这远非一个完美的系统。有时 CA 可能会错误地颁发证书。在这些情况下,可能需要撤销证书。撤销是棘手的,因为颁发的证书在加密上总是正确的; 需要使用带外协议来查明哪些以前有效的证书已被撤销。实际上,其中一些协议并不十分安全,而且许多浏览器无论如何都不会检查它们。

有时候整个隔离中心都会暴露。例如,如果您要闯入 Verisign 并窃取它们的根签名密钥,那么您就可以在世界上欺骗 任何证书。请注意,这不仅仅影响 Verisign 的客户: 即使我的证书是由 Thawte (Verisign 的竞争对手)签署的,这也没有关系。我的证书仍然可以使用 Verisign 的妥协签名密钥进行伪造。

这不仅仅是理论上的。这种事在野外发生过。随后破产。但令人费解的是,他们仍然在业务至今。

即使 CA 没有直接受到威胁,系统中仍然存在其他威胁。例如,政府使用法律强制手段迫使 CA 签署伪造的证书。你的雇主可以在你的雇员电脑上安装他们自己的 CA 证书。在这些不同的情况下,您希望“安全”的流量对于控制该证书的组织来说实际上是完全可见的/可修改的。

一些替代建议,包括 汇聚TACKDANE

尾注

[1] TLS 证书数据根据 X.509标准格式化。X. 509基于 ASN 1(“抽象语法符号 # 1”) ,这意味着它是 没有二进制数据格式。因此,X.509必须是 编码到二进制格式。DER 和 PEM是我所知道的最常见的两种编码。

[2]在实践中,协议实际上转换为对称密码,但这是一个与你的问题无关的细节。

[3]可以推测,CA 实际上在签署您的证书之前验证您是谁。如果他们不这样做,那么我就可以为 google.com 创建一个证书,并请求 CA 对其进行签名。有了这个证书,我就可以在任何“安全”连接到 google.com 的中间人。因此,验证步骤是 CA 运行中的一个非常重要的因素。不幸的是,目前还不清楚这个验证过程在世界各地的数百个 CA 中有多严格。

[4]参见 Mozilla 的 受信任的 CA 列表

HTTPS 是 HTTP安全套接字层的组合,提供客户端(浏览器)和 Web 服务器(应用程序托管在这里)之间的加密通信。

为什么需要它?

HTTPS 对通过网络从浏览器传输到服务器的数据进行加密。所以在传输过程中没人能闻到数据。

如何在浏览器和 Web 服务器之间建立 HTTPS 连接?

  1. 浏览器尝试连接到 https://payment.com
  2. Payment.com 服务器向浏览器发送证书。该证书包括 payment.com 服务器的公钥,以及证明该公钥实际上属于 payment.com 的一些证据。
  3. Browser 验证证书,以确认它具有 payment.com 的适当公钥。
  4. Browser 选择一个随机的新对称密钥 K 用于连接 payment.com 服务器。它在 payment.com 公钥下加密 K。
  5. Payment.com 使用其私钥对 K 进行解密。现在浏览器和支付服务器都知道 K,但是没有其他人知道。
  6. 任何时候浏览器想要发送一些东西到 payment.com,它会用 K 加密它; payment.com 服务器在收到后解密它。任何时候 payment.com 服务器想要发送一些东西到你的浏览器,它都会用 K 加密它。

这个流程可以用下面的图表表示: enter image description here

我已经写了一个小博客文章,其中简要讨论了这个过程。请随意看看。

SSL 握手

下面是其中的一个小片段:

”客户端通过 HTTPS 向服务器发出请求。服务器发送其 SSL 证书 + 公钥的副本。在用本地可信 CA 存储验证服务器的身份之后,客户端生成一个秘密会话密钥,使用服务器的公钥对其进行加密并发送。服务器使用其私钥解密秘密会话密钥,并向客户端发送一个确认。安全通道建立完毕

梅哈斯已经详细解释过了。我将在这个系列中加入我的2分钱。我有许多关于 SSL 握手和证书的博客文章。虽然大部分内容都是围绕 IIS Web 服务器展开的,但这篇文章通常仍然与 SSL/TLS 握手有关。以下是一些可供参考的建议:

不要把 证书SSL当作一个话题。把它们当作两个不同的主题,然后试着看看它们与谁一起工作。这会帮助你回答这个问题。

通过证书存储在通信各方之间建立信任

SSL/TLS 通信仅在信任的基础上工作。因特网上的每台计算机(客户机/服务器)都有一个它维护的根 CA 和中间 CA 的列表。这些是定期更新的。在 SSL 握手过程中,这被用作建立信任的参考。例如,在 SSL 握手期间,当客户端向服务器提供证书时。服务器将尝试检查颁发证书的 CA 是否在其 CA 的列表中。当它不能这样做时,它声明它无法执行证书链验证。(这是答案的一部分。它还查看了 友邦保险。)客户端还对它在 ServerHello 中收到的服务器证书执行类似的验证。 在 Windows 上,您可以通过 PowerShell 看到客户端和服务器的证书存储。从 PowerShell 控制台执行以下命令。

PS 证书: > ls 位置: CurrentUser StoreNames: { TrustedPublisher,ClientAuthIssuer,Root,UserDS... }

位置: LocalMachine StoreNames: { TrustedPublisher, ClientAuthIssuer,远程桌面,Root... }

像 Firefox 和 Opera 这样的浏览器不依赖底层操作系统进行证书管理,它们维护自己独立的证书存储。

SSL 握手同时使用了对称密码和公钥密码。默认情况下发生服务器身份验证。客户端身份验证是可选的,并且取决于服务器端点是否配置为对客户端进行身份验证。请参考我的博客文章,因为我已经详细解释了这一点。

最后一个问题

HTTPS 协议如何识别证书?当证书完成所有的信任/加密/身份验证工作时,HTTP 为什么不能与证书一起工作?

证书 只是一个由 X.509标准定义格式的文件。这是一个电子文件,它证明了一个通信方的身份。 HTTPS = HTTP + SSL 是一个协议,它定义了关于双方应该如何彼此通信的指导方针。

更多信息

  • 为了理解证书,您必须了解什么是证书,并阅读有关证书管理的内容。这些很重要。
  • 理解了这一点之后,继续进行 TLS/SSL 握手。您可以参考 RFC 的。但它们是定义指导方针的框架。包括我在内的一些博客文章对此进行了详细解释。

如果完成了上述活动,那么您将对证书和 SSL 有一个公平的理解。