在SSL握手期间可以使用一个公钥来加密和解密数据吗? [英] Can One Public Key be Used to Encrypt and Decrypt Data during the SSL Handshake?

查看:230
本文介绍了在SSL握手期间可以使用一个公钥来加密和解密数据吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



[UPDATE2]

非常感谢布鲁诺的帮助。



在一次又一次地阅读Bruno的回复和RFC4346(section7.4.2和7.4.3)后,我突然觉得我掌握了要点。 :)

然而,我不确定我是对的,希望有人能确认我的以下理解。感谢。



1.伺服器凭证
SSL和TLS Essential br />
SSL和TLS Essential:保护Web安全 作者:Stephen A. Thomas)


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


Bruno写道,


服务器证书中的公钥不用于验证


我同意布鲁诺的观点,因为证书只是一个私钥签名(加密)的消息还包含其他人的(例如,客户端)公钥,因此客户端应该使用其服务器的公钥的可信副本(通常,web浏览器包括提前几十个这些证书),而不是服务器证书中的公钥,验证服务器的身份。



是不是



2。服务器密钥Exchange

SSL和TLS基本第3.6.2节:


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


Bruno写道,


同样,你不用用公钥签名。你只需要一个键来签名,这是私钥。您使用匹配的公钥验证签名。
...
使用公钥签名是一个不寻常且具有误导性的表达。


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



RFC4346部分 7.4 .2。服务器证书


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



密钥交换算法证书密钥类型 

RSA RSA公钥;证书MUST
允许将密钥用于加密。

DHE_DSS DSS公钥。

DHE_RSA可用于签名的RSA公钥。

DH_DSS Diffie-Hellman密钥。使用
来签署证书的算法必须是DSS。

DH_RSA Diffie-Hellman密钥。使用
来签署证书的算法必须是RSA。


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





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


服务器密钥交换消息由服务器发送。 br />
...

以下密钥交换方法是正确的:



DHE_DSS

DHE_RSA

DH_anon

...

此消息传达加密信息以允许客户端传达预防保密。


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



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



是否正确?

解决方案

密钥加密:




  • 私钥用于签名解密/解密


  • 公开金钥用于验证签名和加密/加密



请参阅 TLS规范词汇表



b b b b
使用公钥加密的消息只能使用关联的私钥
进行解密。相反,用
私钥签署的消息可以用公钥验证。


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


将普通语言或其他数据转换为代码;通过将消息的意义转换为
不能在不知道
解释的秘密方法的情况下被解释的形式来隐藏
,称为密钥;


在使用私钥加密的情况下,您可以有效地抢占数据,要求将消息转回其原始形式不是秘密。因此,在这种情况下谈论加密没有意义。



同样,你并不用一个公钥来签名。你只需要一个键来签名,这是私钥。您可以使用匹配的公钥验证签名。



这是很常见的(即使在TLS规范)说使用证书签名,当真正意味着的是计算具有与证书匹配的私钥的签名。在许多情况下,不是特定的TLS,证书本身与签名一起传送(不管是否选择信任该证书是另一回事)。



表达式例如使用您的证书进行身份验证或使用您的证书签名通常是可以接受的,只要您明白证书用于缩短证书及其私钥,并且它实际上是私人的



我没有你正在引用的书,但这个引语听起来有误导性或不正确(也许在这里不再赘述):


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

服务器证书中的公钥不用于验证服务器的身份。它所做的是确保只有某人/某物与相应的私钥将能够解密你用这个私钥加密的:在这种情况下(验证密钥交换),服务器将证明的预主秘密它通过产生正确的完成消息来知道客户端,基于它已经设法解密的预主控器。



身份绑定由证书本身完成,其是公钥,一些标识符(例如,主题DN和主题备选名称)和可能的各种其他属性(例如,密钥使用,...)的签名组合。
身份验证的这一方(即检查这个证书的所有者)是通过验证证书的完整性,并且您信任它所说的内容(通常是PKI),并通过验证它所属的身份确实是你想连接到的(主机名验证)。这是通过使用证书颁发机构(CA)或外部机制验证证书签名本身来完成的,例如,如果您已经使用知识,明确授予给定证书(可能是自签名)的异常,证书所属的PKI。这个步骤是相当独立的TLS规范,虽然你需要所有这些组合在一起,使通信安全。



这个报价有一个类似的问题(再次,可能从上下文中取出):


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


虽然说使用证书签名是一个常见的表达式(如上所述),但我会说公共密钥肯定是混乱的,因为公共密钥通常与私有密钥相比使用,并且它实际上是用于签名的私有密钥。虽然即使是 TLS规范(第F.1.1.2节)谈到与



我不确定是否(解密)和证书在几个地方,使用公钥签名是一个不寻常和误导的表达。 (加密)在书中或您的添加:


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


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



当它放在 TLS规范中时F.1.1.2部分:


验证服务器的证书后,客户端加密

pre_master_secret与服务器的公钥。通过成功

解码pre_master_secret并生成正确的完成的

消息,服务器会显示它知道与服务器证书对应的私钥

。 p>

您要求的结尾并不完全有意义:


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


公钥不用于验证服务器的身份。您验证您正在与具有与之前提供的证书匹配的私钥的服务器通过其能够解密预主密钥并生成正确的完成消息的事实进行通话。



编辑2:



编辑完毕后,似乎仍在使用sign(encrypt)和验证(解密),好像加密是相同的,签名和验证与解密相同。我再次建议你停止做这些关联:这是4个不同的操作。虽然使用RSA时数学可能是相同的,但这不适用于 DSA ,这只是一种签名算法


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


客户端不接收任何加密握手期间的数据(只有签名数据)。



为了更好地理解,您应该先了解 Diffie-Hellman 及其临时变体(用于DHE密码套件)工作。
(在实践中,我不会把重点放在非临时 DH_RSA / DH_DSS 密码套件上,说实话,我不知道他们'我没有看到任何具有必要的DH属性的证书示例,这些密码套件不在 OpenSSL Java 7 。 DHE / EDH更常见,并且不需要证书中的特殊属性。)



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


$ b $使用这个消息,通过
直接传输RSA加密的秘密或者通过Diffie-Hellman参数的
传输来设置预制秘密


关于其他方面:


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


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


  1. 握手本身,如果成功,保证你正在与服务器证书消息中提供的证书的私钥的服务器通信。如果使用RSA密钥交换,这是由它是唯一一个可以解密客户端发送的客户端密钥交换消息(因为它用公钥加密)的事实保证。如果使用EDH密钥交换,这是保证的,因为服务器在服务器密钥交换消息中签署了它的DH参数,可用这个公钥验证。

  2. 事实上,你可以验证证书本身。这与TLS的工作方式无关,但通常使用 PKI :客户端具有预设的列表可信CA证书,其公钥可用于验证其不知道的新证书(例如服务器证书)中的签名。验证该签名允许客户端将该公钥绑定到标识符(主题DN和/或替换名称)。

  3. 主机名验证:这不足以让您知道您正在与向您提供真实身份证的用户交谈。

当我说你的名字与你想要连接的服务器匹配时,服务器证书中的公钥不用于验证服务器的身份本身,我的意思是公钥未用于验证点2和3.点1保证您正在与具有私钥匹配它提供的证书,但它不告诉你这是什么。验证服务器的身份是到点2,以便能够绑定一个标识符到该密钥/ cert。


When a server sends a Certificate message to a client, the public key in the server's certificate will be used to verify server’s identity(decryption with the public key).

The server follows its Certificate message with a ServerKeyExchange message, the session key information is signed using the same public key contained in the server’s certificate (encryption with the public key).

So I feel a Public key can be used to encrypt and decrypt data as well, am I right? If yes, I wonder why text book just states one key(e.g. public key) is used to encrypt , and the other one(private key) is used to decrypt, rather than mention that a key can be used to both encrypt and decrypt?

[UPDATE2]
Really thanks for Bruno's help.

After reading Bruno's replies and RFC4346(section7.4.2 and 7.4.3) again and again, I suddenly felt I grasp the main points. :)
However, I am not sure I am right, and hope someone can confirm my following understanding. Thanks.

1.Server Certificate
SSL and TLS Essential section 3.6.1:
(SSL and TLS Essential: Securing the Web Author: Stephen A. Thomas)

...the public key in the server's certificate will only be used to verify its(server) identity.

Bruno wrote,

The public key in the server certificate isn't used to verify the server's identity itself.

I agree Bruno's viewpoint now, because a certificate is only a private-key-signed(encrypted) message that also contains someone else's(e.g., a client ) public key, so a client should use its trusted copy of the server's public key (usually, web browsers include dozens of these certificates in advance), instead of the public key in the server certificate, to verify the server's identity.

Is it right?

2.Server Key Exchange
SSL and TLS Essential section 3.6.2:

...the key information is signed using the public key contained in the server's certificate.

Bruno wrote,

Similarly, you don't really sign something with a public key. You only need one of the keys to sign, and that's the private key. You verify the signature with the matching public key. ... "signing with a public key" is an unusual and misleading expression.

I think Bruno is right. The reasons are as follows,

RFC4346 section 7.4.2. Server Certificate

It MUST contain a key that matches the key exchange method, as follows.

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.

So the server sends one of 6 public key types in a certificate first.


RFC4346 section 7.4.3 Server Key Exchange Message

The server key exchange message is sent by the server.
...
This is true for the following key exchange methods:

DHE_DSS
DHE_RSA
DH_anon
...
This message conveys cryptographic information to allow the client to communicate the premaster secret.

The server chooses one of 3 key exchange methods, and uses its private key to sign(encrypt) cryptographic information.

When the client receives the encrypted cryptographic information, it will use the public key in ServerCertificate message to verify(decrypt) and get the plain-text cryptographic information.

Is it right?

解决方案

In public key cryptography:

  • The private key is used for signing and deciphering/decrypting.
  • The public key is used for verifying signatures and enciphering/encrypting.

See the glossary of the TLS specification:

public key cryptography: A class of cryptographic techniques employing two-key ciphers. Messages encrypted with the public key can only be decrypted with the associated private key. Conversely, messages signed with the private key can be verified with the public key.

You cannot encrypt with a private key or decrypt with a public key, not for mathematical reasons, but because it doesn't make sense w.r.t. the definition of encrypt:

To convert ordinary language or other data into code; to hide the meaning of a message by converting it into a form that cannot be interpreted without knowing the secret method for interpretation, called the key; to encode.

In a situation where you "encrypt with the private key", you effectively "scramble" the data indeed, but what's required to turn back the message into its original form is not a secret. Hence, it doesn't make sense to talk about encrypting in this context. Whether the mathematical operations behind it may work one way or the other doesn't matter at this stage.

Similarly, you don't really sign something with a public key. You only need one of the keys to sign, and that's the private key. You verify the signature with the matching public key.

It's quite common (even in the TLS specification) to say "signing with a certificate", when what's really implied is computing the signature with the private key matching the certificate. In many cases, not specifically TLS, the certificate itself is communicated along with the signature (whether-or-not one chooses to trust that certificate is another matter).

Expressions such as "using your certificate to authenticate" or "using your certificate to sign" are generally acceptable, so long as you understand that "certificate" is used there to shorten "certificate and its private key", and that it's in fact the private key that's necessary for those operations.

I don't have the book you're quoting, but this quote sounds misleading or incorrect (perhaps taken out of context here):

...the public key in the server's certificate will only be used to verify its(server) identity.

The public key in the server certificate isn't used to verify the server's identity itself. 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: in this case (authenticated key exchange), the pre-master-secret which the server will prove it knows to the client by producing the correct Finished message, based on the pre-master-master it has managed to decipher.

The identity binding is done by the certificate itself, with is the signed combination of the public key, some identifiers (e.g. Subject DN and Subject Alternative Names) and possibly various other attributes (e.g. key usage, ...). This side of the identity verification (i.e. checking who this certificate belongs to) is established by verifying the integrity of the certificate and that you trust what it says (usually PKI), and by verifying that the identity it belongs to is indeed the one you wanted to connect to (host name verification). This is done by verifying the certificate signature itself using a Certification Authority (CA) or by an outside mechanism, for example if you have explicitly granted an exception for a given certificate (possibly self-signed) using knowledge you have outside the scope of the PKI to which the certificate belongs. This step is rather independent of the TLS specification, although you'll need all these pieces together to make the communication secure.

There's a similar problem with this quote (again, possibly taken out of context):

...the key information is signed using the public key contained in the server's certificate.

Although saying "signed with a certificate" is a common expression (as explained above), I'd say "signing using the public key" is definitely confusing, since "public key" is normally used in contrast to "private key", and it's really the private key that's used for signing. While even the TLS specification (Section F.1.1.2) talks about "signing with a certificate" in a few places, "signing with a public key" is an unusual and misleading expression.

I'm not sure whether "(decrypt)" and "(encrypt)" are in the book or your additions:

the public key in the server's certificate can be used to verify(decrypt) the server's identity and sign(encrypt) the key information(,then the client will use the key information to encrypt pre_master_secret)

You actually verify you're talking to the actual server identified by that certificate because it's the only one capable of deciphering what you've encrypted with its public key (in the client key exchange message).

As it's put in the TLS specification Section F.1.1.2:

After verifying the server's certificate, the client encrypts a
pre_master_secret with the server's public key. By successfully
decoding the pre_master_secret and producing a correct finished
message, the server demonstrates that it knows the private key
corresponding to the server certificate.

What you're asking at the end doesn't completely make sense:

I know the public key can be used to verify server's identity(Certificate message), but I can't understand the public key why can be used to sign the key information, because the client doesn't have the corresponding private key, how does the client verify the key information?

The public key isn't used to verify the server's identity. You verify that you're talking to the server who has the private key matching the certificate it presented earlier by the fact it was able to decipher the pre-master-key and produce the correct finished message.

EDIT 2:

Following your edit, it seems that you're still using "sign(encrypt)" and "verify(decrypt)" as if encrypting was the same as signing and verifying was the same as decrypting. I would suggest once again that you stop making these associations: these are 4 distinct operations. While the maths may be the same when using RSA, this doesn't work for DSA, which is only a signature algorithm (so signing/verifying only).

When the client receives the encrypted cryptographic information, it will use the public key in ServerCertificate message to verify(decrypt) and get the plain-text cryptographic information.

The client doesn't receive any encrypted data during the handshake (only signed data).

For a better general understanding, you should start by trying to understand how Diffie-Hellman and its ephemeral variant (for DHE cipher suites) work. (In practice, I wouldn't focus too much on non-ephemeral DH_RSA/DH_DSS cipher suites. To be honest, I'm not sure whether they're much used. I haven't seen any example of certificate with the necessary DH attributes, and these cipher suites are not in supported lists by OpenSSL or Java 7. DHE/EDH are much more common, and don't require special attributes in the certificate.)

If you use an RSA key exchange algorithm, the client will encrypt the pre-master-key in the client key exchange message; if it's using one of the DH key exchange algorithms, it will send its DH parameters so that client and server can agree on a pre-master-key (in this case, the client will have checked that the server's DH parameters come from the right server by verifying the signature of the server key exchange message sent beforehand). See description of the Client Key Exchange Message:

With this message, the premaster secret is set, either though direct transmission of the RSA-encrypted secret or by the transmission of Diffie-Hellman parameters that will allow each side to agree upon the same premaster secret.

Regarding the other points:

a certificate is only a private-key-signed(encrypted) message that also contains someone else's(e.g., a client ) public key, so a client should use its trusted copy of the server's public key (usually, web browsers include dozens of these certificates in advance), instead of the public key in the server certificate, to verify the server's identity.

Three things happen to verify you're talking to the right server:

  1. The handshake itself, if successful, guarantees that you're talking to the server that has the private key for the certificate it has presented in the server certificate message. If using RSA key exchange, this is guaranteed by the fact it's the only one that can decipher what the client sent in the client key exchange message (since it's encrypted with the public key); if using an EDH key exchange, this is guaranteed because the server signed its DH parameters in the server key exchange message, verifiable with this public key.
  2. The fact that you can verify the certificate itself. This is rather independent of how TLS works, but it's usually done using a PKI: the client has a pre-set list of trusted CA certificates, the public keys of which can be used to verify the signature in new certificates it doesn't already know about (such as the server certificate). Verifying that signature allows the client to bind that public key to an identifier (Subject DN and/or alt. name). This gives you the identity of the server to which the client is talking.
  3. The host name verification: it's not good enough to know that you're talking to someone who's presented you a genuine ID that's valid for them, you also need to check that the name matches the server you intended to connect to.

When I said "The public key in the server certificate isn't used to verify the server's identity itself", I meant that the public key wasn't used to verify points 2 and 3. Point 1 guarantees you that you're talking to the server that has the private key matching the certificate it presented, but it doesn't tell you who this is. Verifying the identity of the server is is up to point 2, so as to be able to bind an identifier to that key/cert.

这篇关于在SSL握手期间可以使用一个公钥来加密和解密数据吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆