【问题标题】:Can One Public Key be Used to Encrypt and Decrypt Data during the SSL Handshake?SSL握手期间可以使用一个公钥加密和解密数据吗?
【发布时间】:2019-12-12 12:09:02
【问题描述】:

当服务器向客户端发送证书消息时,服务器证书中的公钥将用于验证服务器的身份(用公钥解密)。

服务器在其证书消息之后使用 ServerKeyExchange 消息,会话密钥信息使用服务器证书中包含的相同公钥进行签名(使用公钥加密)。

所以我觉得公钥也可以用来加密和解密数据,对吗? 如果是,我想知道为什么教科书只说明一个密钥(例如公钥)用于加密,而另一个(私钥)用于解密,而不是提到一个密钥可以用于加密和解密?

[更新2]
非常感谢布鲁诺的帮助。

在反复阅读了 Bruno 的回复和 RFC4346(第 7.4.2 和 7.4.3 节)之后,我突然觉得我抓住了要点。 :)
但是,我不确定我是否正确,希望有人能证实我的以下理解。谢谢。

1.服务器证书
SSL 和 TLS 基础 3.6.1 部分:
SSL 和 TLS 基础:保护网络作者:Stephen A. Thomas)

...服务器证书中的公钥将仅用于验证其(服务器)身份。

布鲁诺写道,

服务器证书中的公钥不用于验证服务器本身的身份。

我现在同意 Bruno 的观点,因为证书只是一个私钥签名(加密)的消息,其中还包含其他人(例如客户端)的公钥,因此客户端应该使用服务器公钥的可信副本密钥(通常,Web 浏览器预先包含几十个这样的证书),而不是服务器证书中的公钥,用于验证服务器的身份。

对吗?

2.服务器密钥交换
SSL 和 TLS 基本部分 3.6.2:

...密钥信息使用服务器证书中包含的公钥进行签名。

布鲁诺写道,

同样,您并没有真正使用公钥签署某些东西。您只需要其中一个密钥即可签名,那就是私钥。您使用匹配的公钥验证签名。 ... “使用公钥签名”是一种不寻常且具有误导性的表达方式。

我认为布鲁诺是对的。原因如下,

RFC4346 部分7.4.2. Server Certificate

它必须包含一个与密钥交换方法相匹配的密钥,如下所示。

密钥交换算法证书密钥类型 RSA RSA 公钥;证书必须 允许密钥用于加密。 DHE_DSS DSS 公钥。 DHE_RSA 可用于签名的 RSA 公钥。 DH_DSS Diffie-Hellman 密钥。使用的算法 签署证书必须是 DSS。 DH_RSA Diffie-Hellman 密钥。使用的算法 签署证书必须是 RSA。

因此服务器首先在证书中发送 6 种公钥类型之一。


RFC4346 部分 [7.4.3 服务器密钥交换消息][2]
>服务器密钥交换消息由服务器发送。
>...
>这适用于以下密钥交换方法: > DHE_DSS
DHE_RSA
DH_anon
>...
>此消息传达加密信息以允许客户端传达预主密钥。

服务器选择 3 种密钥交换方法之一,并使用其私钥对加密信息进行签名(加密)。

客户端收到加密后的密码信息后,会使用ServerCertificate消息中的公钥进行验证(解密),得到明文的密码信息。

对吗?

【问题讨论】:

  • ServerKeyExchange 消息使用服务器证书消息中的公钥。仔细阅读 TLS 规范。
  • 如果您在此过程中坚持使用术语“签名”和“验证”,而不是“签名(加密)”和“验证(解密)”,您会做得更好。否则,您只会使自己感到困惑。加密和解密以相反的方式使用密钥。引擎盖下都是一样的,但不要让它泄漏到您的功能描述中。
  • '服务器使用 ServerKeyExchange 消息跟随其证书消息,会话密钥信息使用服务器证书中包含的相同公钥进行签名'不正确。它使用服务器的 private 密钥进行签名。

标签: ssl cryptography


【解决方案1】:

在公钥加密中:

  • 私钥用于签名解密/解密
  • 公钥用于验证签名加密/加密

glossary of the TLS specification

公钥加密: 一类使用双密钥密码的密码技术。 用公钥加密的消息只能用 关联的私钥。相反,用 私钥可以用公钥验证。

你不能用私钥加密或用公钥解密,不是因为数学原因,而是因为它没有意义。 encrypt的定义:

将普通语言或其他数据转换为代码;隐藏 通过将信息转换成一种形式来表达信息的意义 不知道秘诀就无法解释 解释,称为关键;进行编码。

在您“使用私钥加密”的情况下,您确实有效地“打乱”了数据,但将消息恢复为原始形式所需的并不是秘密。因此,在这种情况下谈论加密是没有意义的。在这个阶段,它背后的数学运算是否可以以一种或另一种方式起作用并不重要。

同样,您并没有真正使用公钥签署某些东西。您只需要其中一个密钥即可签名,那就是私钥。您使用匹配的公钥验证签名。

说“使用证书签名”是很常见的(即使在 TLS 规范中),而真正暗示的是使用与证书匹配的私钥计算签名。在许多情况下,不是特别是 TLS,证书本身与签名一起进行通信(是否选择信任该证书是另一回事)。

“使用您的证书进行身份验证”或“使用您的证书进行签名”之类的表达通常是可以接受的,只要您了解“证书”用于缩短“证书及其私钥”,并且它是实际上是这些操作所必需的私钥。

我没有你引用的那本书,但这个引用听起来有误导性或不正确(可能在这里断章取义):

...服务器证书中的公钥将仅用于 验证其(服务器)身份。

服务器证书中的公钥不用于验证服务器本身的身份。它的作用是确保只有拥有相应私钥的某人/某物才能破译您使用此公钥加密的内容:在这种情况下(经过身份验证的密钥交换),服务器将证明的 pre-master-secret它通过根据它设法破译的 pre-master-master 生成正确的 Finished 消息来向客户端了解。

身份绑定由证书本身完成,它是公钥、一些标识符(例如,主题 DN 和主题备用名称)以及可能的各种其他属性(例如,密钥使用,...)的签名组合。 身份验证的这一侧(即检查此证书属于谁)是通过验证证书的完整性以及您信任它所说的内容(通常是 PKI)以及通过验证它所属的身份确实是您的身份来建立的想要连接到(主机名验证)。这是通过使用证书颁发机构 (CA) 或外部机制验证证书签名本身来完成的,例如,如果您使用您在证书范围之外的知识明确授予给定证书的例外(可能是自签名)证书所属的PKI。此步骤与 TLS 规范相当独立,尽管您需要将所有这些部分组合在一起以确保通信安全。

这句话也有类似的问题(同样,可能断章取义):

...密钥信息使用包含在 服务器的证书。

虽然说“用证书签名”是一种常见的表达方式(如上所述),但我会说“使用公钥签名”肯定会令人困惑,因为“公钥”通常用于与“私钥”形成对比",并且它确实是用于签名的私钥。尽管TLS specification (Section F.1.1.2) 在一些地方谈到“使用证书签名”,但“使用公钥签名”是一种不寻常且具有误导性的表达方式。

我不确定“(解密)”和“(加密)”是否在书中或您的补充中:

服务器证书中的公钥可用于 验证(解密)服务器的身份并签署(加密)密钥 information(,则客户端将使用密钥信息进行加密 pre_master_secret)

您实际上验证了您正在与该证书标识的实际服务器对话,因为它是唯一能够解密您使用其公钥(在客户端密钥交换消息中)加密的内容的服务器。

正如它放在TLS specification Section F.1.1.2

在验证服务器的证书后,客户端加密一个
pre_master_secret 与服务器的公钥。通过成功
解码 pre_master_secret 并生成正确的成品
消息,服务器证明它知道私钥
对应服务器证书。

你最后问的并不完全有道理:

我知道公钥可以用来验证服务器的 身份(证书消息),但我无法理解公钥 为什么可以用来签名关键信息,因为客户端 没有对应的私钥,客户端如何验证 关键信息?

公钥不用于验证服务器的身份。您验证您正在与拥有与之前提供的证书匹配的私钥的服务器交谈,因为它能够解密预主密钥并产生正确的完成消息。

编辑 2:

在您进行编辑后,您似乎仍在使用“签名(加密)”和“验证(解密)”,就好像加密与签名相同,验证与解密相同。我再次建议您停止进行这些关联:这是 4 种不同的操作。虽然使用 RSA 时的数学运算可能相同,但这不适用于 DSA,它只是一种签名算法(因此仅用于签名/验证)。

当客户端收到加密的密码信息时,它 将使用 ServerCertificate 消息中的公钥 验证(解密)并获取明文密码信息。

客户端在握手期间没有收到任何加密数据(只有签名数据)。

为了更好地理解,您应该首先尝试了解 Diffie-Hellman 及其 ephemeral variant(用于 DHE 密码套件)的工作原理。 (在实践中,我不会过多关注非临时性DH_RSA/DH_DSS 密码套件。老实说,我不确定它们是否被广泛使用。我还没有看到任何具有必要 DH 的证书示例属性,并且这些密码套件不在OpenSSLJava 7 支持的列表中。DHE/EDH 更为常见,并且不需要证书中的特殊属性。)

如果使用RSA密钥交换算法,客户端将加密客户端密钥交换消息中的pre-master-key;如果它使用其中一种 DH 密钥交换算法,它将发送其 DH 参数,以便客户端和服务器可以就预主密钥达成一致(在这种情况下,客户端将检查服务器的 DH 参数是否来自正确的服务器通过验证预先发送的服务器密钥交换消息的签名)。查看Client Key Exchange Message的描述:

通过此消息,设置了预主密钥,尽管 直接传输 RSA 加密的秘密或由 Diffie-Hellman 参数的传输,这将允许每个 方同意相同的 premaster secret。

关于其他方面:

证书只是一个私钥签名(加密)的消息,它 还包含其他人(例如,客户端)的公钥,因此客户端 应使用其受信任的服务器公钥副本(通常,Web 浏览器预先包含了几十个这样的证书),而不是 服务器证书中的公钥,用于验证服务器的 身份。

验证您正在与正确的服务器通话时会发生三件事:

  1. 握手本身,如果成功,则保证您正在与服务器交谈,该服务器拥有服务器证书消息中提供的证书的私钥。如果使用 RSA 密钥交换,这是因为它是唯一可以解密客户端在客户端密钥交换消息中发送的内容的事实(因为它是用公钥加密的);如果使用 EDH 密钥交换,这是有保证的,因为服务器在服务器密钥交换消息中签署了它的 DH 参数,可使用此公钥进行验证。
  2. 您可以验证证书本身。这与 TLS 的工作方式相当独立,但通常使用PKI 完成:客户端有一个预设的受信任 CA 证书列表,其公钥可用于验证新证书中的签名。 t 已经知道(例如服务器证书)。验证该签名允许客户端将该公钥绑定到一个标识符(主题 DN 和/或替代名称)。这为您提供了客户端正在与之通信的服务器的身份。
  3. 主机名验证:知道您正在与向您提供对其有效的真实 ID 的人交谈是不够的,您还需要检查该名称是否与您打算连接的服务器匹配。

当我说“服务器证书中的公钥不用于验证服务器本身的身份”时,我的意思是公钥不用于验证第 2 点和第 3 点。第 1 点向您保证“正在与具有与其提供的证书匹配的私钥的服务器交谈,但它不会告诉您这是谁。验证服务器的身份直到第 2 点,以便能够将标识符绑定到该密钥/证书。

【讨论】:

  • What it does is ensuring that only someone/something with the corresponding private key will be able to decipher what you've encrypted with this private key 这是一个错字吗?你是说public key这里吗?
  • @XtremeBiker 是的,它应该是“用这个公共密钥加密”,确实,对不起。
【解决方案2】:

在像 RSA 这样的 PPK 算法中,您有两个不同的通信渠道。使用公钥加密的信息只有私钥拥有者才能读取,使用私钥加密的信息只有公钥拥有者才能读取。

事实上,选择哪一半是“公开的”是完全任意的。

现在,实际上这并不重要;整个世界都可以访问公钥,因此用私有部分加密某些东西不会做任何事情来保护它。但是您可以使用它进行身份验证:由于只有一个持有者拥有私钥,如果使用它对消息进行有效加密,那么私钥持有者一定是作者。

这就是为什么你的书没有说私钥用于加密:因为它用于完整性,而不是机密性,因为使用它密封的任何消息任何拥有非秘密公共部分的人都可以阅读。虽然完整性验证机制在技术上是加密(它是使用模幂进行加密),但在密码学基础上下文中提及这一点会令人困惑,因为这不是人们在听到“加密”时的想法——他们认为是“隐私” .

【讨论】:

  • 选择哪一半是公开的并不是那么随意。对于 RSA,私有指数必须足够长(例如,与模数相似的长度),而公共指数非常短(通常是相同的值:65537)。
  • @Bruno 这是惯例,不是要求。 RSA 算法不排除有两个近似等价的指数。
  • 确实,我说的更多是从实用的角度。你是对的。
【解决方案3】:

我也有同样的不安,因为很难在不陷入技术漏洞的情况下提问。快速,简单的答案:不管方法细节如何,是的,您可以从一个密钥进行逆向工程和解密(最后只是数学),但由于操作的复杂性,使用长值(您可以使用 ie.a 4096 位值)将使反向操作变得永恒,因此您必须使用一台仍然不存在的大机器或无限期等待,使其无法生存......直到有人想出一个快速的方法来做到这一点。

可能想看看: http://www.usna.edu/CS/si110arch/si110AY12F/lec/l29/lec.html

【讨论】:

  • 这实际上并没有回答问题。这不是破解密钥,而是密钥的功能用途。
猜你喜欢
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
相关资源
最近更新 更多