数字证书、签名和 ssl 的流程如何工作?

信息安全 http tls 协议 电子签名
2021-08-29 04:22:27

我一直在尝试了解 ssl 的工作原理。让我们考虑客户端和服务器通信,而不是 Alice 和 Bob。服务器具有从 CA 获取的数字证书。它还具有公钥和私钥。服务器想向客户端发送消息。服务器的公钥已经可供客户端使用。

假设 ssl 握手已完成。

服务器到客户端

  • 服务器将其公钥附加到消息中。
  • 在(消息+公钥)上运行哈希函数。结果称为 HMAC。
  • 使用它的私钥加密 HMAC。结果称为数字签名。
  • 连同数字证书一起发送给客户。
  • 客户端检查证书并发现它来自预期的服务器。
  • 使用服务器的公钥解密 HMAC。
  • 对(消息+公钥)运行散列函数以获取原始消息。

客户端到服务器

  • 客户端在(消息+公钥)上运行哈希函数,然后使用相同的公钥进行加密。
  • 服务器使用私钥解密,对结果数据运行散列函数以获取消息。

请让我知道我的理解是否正确。

4个回答

您的帖子中有一些混淆。首先,HMAC不是哈希函数稍后会详细了解 HMAC。

哈希函数

散列函数是一种完全公开的算法(其中没有关键),它以一种真正无法解开的方式将位混合在一起:任何人都可以对任何数据运行散列函数,但从散列输出中找到数据似乎是远远超出我们的智慧。哈希输出具有固定大小,通常为 256 位(使用 SHA-256)或 512 位(使用 SHA-512)。输出 160 位的 SHA-* 函数称为 SHA-1,而不是 SHA-160,因为留给自己设备的密码学家只能在那么长的时间内保持合理,而且肯定不会超过 5 品脱。

签名算法

签名算法使用一对在数学上链接在一起的密钥,即私钥公钥(从公钥重新计算私钥在理论上是可行的,但在实践中很难做到,即使使用真正的大型计算机,这是为什么在私钥保持私有的情况下公开密钥并公开)。使用密钥的数学结构,签名算法允许:

  • 使用私钥在某些输入数据上生成签名(签名是一个相当紧凑的数学对象,例如,对于典型的 RSA 签名只有几百字节);
  • 使用公钥验证某些输入数据的签名。验证将签名、输入数据和公钥作为参数,并返回“完美,伙计!” 或“伙计,这些不匹配”。

对于安全的签名算法,产生签名值和输入数据以使具有给定公钥的验证算法说“好”是不可行的,除非您知道相应的私钥,在这种情况下,它既简单又高效。请注意小字:没有私钥,即使您可以根据需要选择数据和签名,您也无法想象出一些与公钥一起使用的数据和签名值。

“据说不可行”意味着世界上所有聪明的密码学家都研究了几年,但即使在第五品脱之后也没有找到方法。

大多数(实际上是所有)签名算法都首先使用散列函数处理输入数据,然后单独处理散列值。这是因为签名算法需要某些给定集合中的数学对象,这些对象的大小是有限的,因此它们需要处理“不太大”的值,例如散列函数的输出。由于散列函数的性质,事情进展顺利(签署散列输出与签署散列输入一样好)。

密钥交换和非对称加密

密钥交换协议是一种协议,其中双方相互抛出数学对象,每个对象都可能与他们为它们保留的一些秘密值相关联,其方式与公钥/私钥对非常相似。在密钥交换结束时,双方可以计算出一个共同的“值”(又一个数学对象),这完全避免了任何观察到在线路上交换的比特的人的掌握。一种常见的密钥交换算法是非对称加密非对称加密使用公钥/私钥对(不一定与签名算法相同):

  • 使用公钥,您可以加密一段数据。该数据通常在大小上受到限制(例如,对于具有 1024 位公钥的 RSA,不超过 117 个字节)。加密结果,你猜怎么着,是一个可以编码成字节序列的数学对象。
  • 使用私钥,您可以解密,即进行反向操作并恢复初始输入数据。假设没有私钥,运气不好。

然后密钥交换协议如此运行:一方选择一个随机值(随机字节序列),用对等方的公钥加密,然后发送给他。对等方使用他的私钥解密,并恢复随机值,即共享秘密。

历史上对签名的解释是:“用私钥加密,用公钥解密”。忘记那个解释。这是错误的。这可能仅适用于特定算法 (RSA),而且,同样,仅适用于实际上没有任何体面安全性的 RSA 的低级版本。所以,数字签名不是“反向”的非对称加密。

对称密码学

一旦双方拥有共享的秘密值,他们就可以使用对称密码学以保密的方式交换进一步的数据。之所以称为对称,是因为双方拥有相同的密钥,即相同的知识,即相同的权力。不再有私人/公共二分法。使用了两个原语:

  • 对称加密:如何破坏数据并在以后解除它。
  • 消息验证码:“密钥校验和”:只有知道密钥的人才能计算某些数据的 MAC(它就像一个签名算法,其中私钥和公钥是相同的——所以“公钥”最好不要公开!)。

HMAC 是一种以智能方式构建在散列函数之上的 MAC,因为有许多非智能方法可以做到这一点,并且由于散列函数提供和不提供什么的细微细节而失败。

证书

证书是公钥的容器使用上面解释的工具,人们可以开始设想服务器将拥有一个公钥,客户端将使用该公钥与服务器进行密钥交换。但是客户端如何确保他使用的是正确的服务器的公钥,而不是一个狡猾的攻击者,一个狡猾地冒充服务器的恶棍?这就是证书发挥作用的地方。证书由专门验证物理身份的人员签署;它被称为证书颁发机构CA“在现实生活中”(例如在酒吧)与服务器会面,验证服务器身份,从服务器自己获取服务器公钥,并签署整个批次(服务器身份公钥)。这会产生一个漂亮的捆绑包,称为证书。证书代表CA对名称和公钥相互匹配的保证(希望 CA 不会太轻信,因此保证是可靠的——最好 CA在其第五品脱之后不签署证书)。

客户端在看到证书后,可以相对于 CA 公钥验证证书上的签名,从而确信服务器公钥确实属于预期的服务器。

但是,你会告诉我,我们得到了什么?我们还必须知道一个公钥,即 CA 公钥。我们如何验证那个?好吧,我们可以使用另一个CA。这只是解决了问题,但最终可能会导致先验地知道来自 über-CA 的唯一或少数未由其他任何人签名的公钥的问题。深思熟虑后,微软在 Internet Explorer 本身深处嵌入了大约一百个这样的“根公钥”(也称为“信任锚”)。这就是信任的起源(准确地说,你丧失了对雷德蒙德公司的信任基础——现在你明白比尔盖茨是如何成为世界上最富有的人了吗?)。

SSL

现在让我们把它们放在 SSL 协议中,现在称为TLS(当它是 Netscape Corporation 的财产时,“SSL”是协议名称)。

客户端希望与服务器对话。它发送一条消息(“ClientHello”),其中包含一堆管理数据,例如客户端支持的加密算法列表。

服务器通过告知将使用哪些算法来响应(“ServerHello”);然后服务器发送他的证书(“Certificate”),可能带有一些 CA 证书,以防客户端可能需要它们(不是根证书,而是中间的下级 CA 证书)。

客户端验证服务器证书并从中提取服务器公钥。客户端生成一个随机值(“pre-master secret”),使用服务器公钥对其进行加密,并将其发送服务器(“ClientKeyExchange”)。

服务器解密消息,获得预主控,并从中派生用于对称加密和 MAC 的密钥。客户端执行相同的计算。

客户端发送验证消息(“完成”),该消息使用派生密钥进行加密和 MAC 化。服务器验证 Finished 消息是否正确,并发送自己的“Finished”消息作为响应。此时,客户端和服务器都拥有他们需要的所有对称密钥,并且知道“握手”已经成功。然后使用对称加密和 MAC 交换应用程序数据(例如 HTTP 请求)。

除了握手之外,该过程中不涉及公钥或证书。只是对称加密(例如 3DES、AES 或 RC4)和 MAC(通常是带有 SHA-1 或 SHA-256 的 HMAC)。

经过一番挣扎。我对 SSL、非对称密钥加密、数字证书 (DC) 和数字签名 (DS) 之间的区别有以下理解。

什么是数字证书,也称为公钥证书?

DC是一种电子文档,它使用数字签名将公钥与姓名、地址等身份信息绑定

证书内容:公钥证书

最重要的是,签名算法、颁发者和公钥。

什么是非对称密钥加密和数字签名?

用一个例子来解释。

两台机器都有一对加密密钥——一个公共加密密钥和一个私有解密密钥。

机器 A 可以访问机器 B 的公钥和证书。
机器 B 可以访问机器 A 的公钥和证书。

机器 A 到机器 B

在机器-A:

  • 哈希函数(数据)=哈希
  • 使用 Machine-A 的私钥加密(哈希) = DS
  • 将数据附加到 DS 和 DC = Data+DS+DC
  • 使用 Machine-B 的公钥加密(Data+DS+DC)。
  • 将其发送到机器-B。

在机器-B:

  • 使用 Machine-B 的私钥解密(Data+DS+DC)。
  • 验证 DC 以验证机器 A。
  • 使用 Machine-A 的公钥解密 (DS) = Hash#1
  • Hash_function(Data) = Hash#2
  • if(Hash#1 == Hash#2) 数据和签名有效。

机器 B 到机器 A

该过程现在与上述完全相反。

什么是 SSL/TLS?

TLS 协议允许客户端/服务器应用程序以一种旨在防止窃听和篡改的方式通过网络进行通信。在大多数客户端-服务器通信中,只需要对服务器进行身份验证。TLS 简化了非对称密钥加密以有效利用这一现象。 安全链路层

客户端和服务器示例。

服务器具有从 CA 获取的数字证书。它还具有公钥和私钥。

用户单击以开头的 URL

https://

此会话需要安全连接。浏览器在 HTTPS TCP 端口 443 上建立 TCP 连接。

  1. 客户端 > 服务器:SYN
  2. 客户端<服务器:SYN+ACK
  3. 客户端>服务器:ACK

    新 TCP 连接上的 SSL 握手:

  4. 客户端 > 服务器:CLIENT_HELLO

    客户端向服务器发送 CLIENT_HELLO 命令,其中包括:

    • 客户端支持的最高 SSL 和 TLS 版本。
    • 客户端支持的密码。密码按优先顺序列出。
    • 客户端支持的数据压缩方法。
    • 会话 ID。如果客户端正在启动新的 SSL 会话,则会话 ID 为 0。
    • 客户端生成的随机数据,用于密钥生成过程。
  5. 客户端<服务器:SERVER_HELLO

    服务器向客户端发送 SERVER_HELLO 命令,其中包括:

    • 将用于 SSL 会话的 SSL 或 TLS 版本。
    • 将用于 SSL 会话的密码。
    • 将用于 SSL 会话的数据压缩方法。
    • SSL 会话的会话 ID。
    • 服务器生成的用于密钥生成过程的随机数据。
  6. 客户端 < 服务器:证书(公钥)

    服务器发送 CERTIFICATE 命令。它包括服务器证书。

  7. 客户端 < 服务器:SERVER_DONE

    服务器发送 SERVER_DONE 命令。此命令表示服务器已完成 SSL 握手的这一阶段。

  8. 客户端 > 服务器:CERTIFICATE_VERIFY

    客户端通知服务器它已经验证了服务器的证书

  9. 客户端 > 服务器:

    使用到目前为止在握手中生成的所有数据,客户端(在服务器的合作下,取决于所使用的密码)为会话创建预主密钥,用服务器的公钥加密它(从服务器的证书中获得) ),然后将加密的 pre-master secret 发送到服务器。

    服务器使用其私钥解密预主密钥,然后执行一系列步骤来生成主密钥。

    客户端还对 pre-master secret 执行相同的一系列步骤以生成相同的 master secret。

    注意:在需要对客户端进行身份验证的情况下,客户端还会签署另一条数据,该数据对于此握手是唯一的,并且客户端和服务器都知道。在这种情况下,客户端将签名数据和客户端自己的证书连同加密的预主密钥一起发送到服务器。

  10. 客户端<>服务器:

    客户端和服务器都使用主密钥生成会话密钥,这些密钥是对称密钥,用于加密和解密在 SSL 会话期间交换的信息并验证其完整性。

    注意:从现在开始它是对称密钥加密。

  11. 客户端 > 服务器:

    客户端向服务器发送一条消息,通知它将来来自客户端的消息将使用会话密钥进行加密。

  12. 客户端 > 服务器:已完成

    客户端然后发送一个单独的(加密的)消息,指示它的握手部分已完成。

  13. 客户端<服务器:

    服务器向客户端发送一条消息,通知它将来来自服务器的消息将使用会话密钥进行加密。

  14. 客户端<服务器:已完成

    服务器发送一个单独的(加密的)消息,表明它的握手部分已经完成。

    SSL 握手现已完成,会话开始。客户端和服务器使用会话密钥来加密和解密它们发送给彼此的数据并验证其完整性。

对于“幕后”更详细的解释,我还可以推荐以下文章: Jeff Moser的 The First Few Milliseconds of an HTTPS Connection本文使用 HTTPS 通信会话的数据包捕获来说明协议的工作原理。看到我们正在谈论的事情在行动中很有趣,它清除了许多“黑暗”点。

不完全的; 证书仅在初始 SSL 握手期间或 SSL 重新协商期间发挥作用。之后,将使用对称密码,例如 AES、(3)DES 或 RC4。公钥加密通常比对称加密更昂贵,因此通常用于在开始时就对称密钥达成一致。