在SSL握手期间可以使用一个公钥来加密和解密数据吗?

Mat*_*son 9 ssl cryptography

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

服务器使用ServerKeyExchange消息跟随其Certificate消息,使用服务器证书中包含的相同公钥(使用公钥加密)对会话密钥信息进行签名.

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

[UPDATE2]
真的感谢布鲁诺的帮助.

在一次又一次阅读Bruno的回复和RFC4346(第7.4.2和7.4.3节)后,我突然觉得我掌握了要点.:)
但是,我不确定我是对的,希望有人能证实我的理解.谢谢.

1.Server证书
SSL和TLS的基本部分3.6.1:
(SSL和TLS是必不可少的:保护网络 作者:斯蒂芬A.托马斯)

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

布鲁诺写道,

服务器证书中的公钥不用于验证服务器的标识本身.

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

这样对吗?

2.Server Key Exchange
SSL和TLS Essential部分3.6.2:

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

布鲁诺写道,

同样,您并没有使用公钥真正签名.您只需要其中一个密钥进行签名,这就是私钥.您使用匹配的公钥验证签名......."用公钥签名"是一种不寻常和误导性的表达.

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

RFC4346第7.4.2.服务器证书

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

Key Exchange Algorithm           Certificate Key Type

RSA RSA public key; the certificate MUST allow the key to be used for encryption. DHE_DSS DSS public key. DHE_RSA RSA public key that can be used for signing. DH_DSS Diffie-Hellman key. The algorithm used to sign the certificate MUST be DSS. DH_RSA Diffie-Hellman key. The algorithm used to sign the certificate MUST be RSA.
Run Code Online (Sandbox Code Playgroud)

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


RFC4346第7.4.3服务器密钥交换消息

服务器密钥交换消息由服务器发送.
......
以下密钥交换方法都是如此:

DHE_DSS
DHE_RSA
DH_anon
...
此消息传达加密信息以允许客户端传送预主密钥.

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

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

这样对吗?

Bru*_*uno 12

在公钥加密中:

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

请参阅TLS规范术语表:

公钥密码术:一种采用双密钥密码的密码技术.使用公钥加密的消息只能使用关联的私钥解密.相反,可以使用公钥验证使用私钥签名的消息.

您不能使用私钥加密或使用公钥解密,不是出于数学原因,而是因为加密的定义没有意义:

将普通语言或其他数据转换为代码; 通过将消息转换为一种在不知道解密的秘密方法(称为密钥)的情况下无法解释的形式来隐藏消息的含义; 编码.

在您"使用私钥加密"的情况下,您实际上有效地"加扰"了数据,但将消息转换回其原始形式所需要的并不是秘密.因此,在这种情况下谈论加密是没有意义的.在这个阶段,它背后的数学运算是否可以以某种方式工作并不重要.

同样,您并没有使用公钥真正签名.您只需要其中一个密钥进行签名,这就是私钥.您使用匹配的公钥验证签名.

说"使用证书签名"是非常常见的(即使在TLS规范中),当真正暗示的是使用与证书匹配的私钥计算签名时.在许多情况下,不是特定的TLS,证书本身与签名一起传递(无论是否选择信任该证书是另一个问题).

诸如"使用您的证书进行身份验证"或"使用您的证书进行签名"等表达通常是可以接受的,只要您了解在那里使用"证书"来缩短"证书及其私钥",并且它实际上是这些操作所必需的私钥.

我没有你引用的那本书,但这句话听起来有误导性或不正确(可能在这里脱离了上下文):

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

服务器证书中的公钥不用于验证服务器的标识本身.它的作用是确保只有具有相应私钥的某人/某些东西才能解密您使用此私钥加密的内容:在这种情况下(经过身份验证的密钥交换),服务器将证明的预主密钥它通过生成正确的Finished消息来了解客户端,该消息基于它已设法解密的pre-master-master.

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

这句话也有类似的问题(再次,可能脱离了上下文):

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

虽然说"用证书签名"是一个常见的表达方式(如上所述),但我说"使用公钥签名"肯定令人困惑,因为"公钥"通常与"私钥"形成对比,并且它真的是用于签名的私钥.虽然TLS规范(第F.1.1.2节)在几个地方谈到"使用证书签名",但"使用公钥签名"是一种不同寻常且误导性的表达.

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

服务器证书中的公钥可用于验证(解密)服务器的身份并签名(加密)密钥信息(然后客户端将使用密钥信息加密pre_master_secret)

实际上,您确认您正在与该证书所标识的实际服务器进行通信,因为它是唯一能够使用其公钥解密您已加密的内容的服务器(在客户端密钥交换消息中).

正如TLS规范第F.1.1.2节所述:

验证服务器的证书后,客户端
使用服务器的公钥加密pre_master_secret.通过成功
解码pre_master_secret并生成正确的完成
消息,服务器演示它知道
对应于服务器证书的私钥.

你最后要问的是不完全有意义的:

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

公钥不用于验证服务器的身份.验证您是否正在与具有与之前提供的证书匹配的私钥的服务器进行通信,因为它能够解密预主密钥并生成正确的完成消息.

编辑2:

在您编辑之后,您似乎仍在使用"签名(加密)"和"验证(解密)",就像加密与签名和验证一样与解密相同.我再次建议你停止这些关联:这是4个不同的操作.虽然使用RSA时数学可能相同,但这对DSA不起作用,DSA只是一种签名算法(因此只签名/验证).

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

客户端在握手期间不接收任何加密数据(仅签名数据).

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

如果使用RSA密钥交换算法,客户端将在客户端密钥交换消息中加密预主密钥; 如果它使用DH密钥交换算法之一,它将发送其DH参数,以便客户端和服务器可以就预主密钥达成一致(在这种情况下,客户端将检查服务器的DH参数是否来自右侧服务器通过验证预先发送的服务器密钥交换消息的签名).请参阅客户端密钥交换消息的说明:

利用该消息,通过直接传输RSA加密的秘密或通过传输Diffie-Hellman参数来设置预主密钥,该参数将允许每一方同意相同的预主密钥.

关于其他问题:

证书只是一个私钥签名(加密)消息,也包含其他人(例如客户端)公钥,因此客户端应使用其服务器公钥的可信副本(通常,Web浏览器包含其中的几十个提前证书),而不是服务器证书中的公钥,以验证服务器的身份.

有三件事情可以证明你正在与正确的服务器交谈:

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

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