SSL握手过程中是否可以使用一个公钥来加解密数据?

发布于 2025-01-06 05:53:05 字数 2087 浏览 1 评论 0原文

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

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

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

[更新2]
真的很感谢Bruno的帮助。

一遍又一遍地阅读Bruno的回复和RFC4346(section7.4.2和7.4.3)后,我突然觉得我抓住了要点。 :)
但是,我不确定我的理解是否正确,希望有人能证实我的以下理解。谢谢。

1.服务器证书
SSL 和 TLS 基本第 3.6.1 节:
SSL 和 TLS 基础:保护 Web 作者:Stephen A. Thomas)

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

布鲁诺写道,

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

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

是吗?

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

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

布鲁诺写道,

同样,您实际上并没有使用公钥签署某些内容。您只需要其中一把密钥即可进行签名,这就是私钥。您使用匹配的公钥验证签名。 ... “使用公钥签名”是一种不寻常且具有误导性的表达方式。

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

RFC4346章节7.4.2。服务器证书

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

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

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


RFC4346 section [7.4.3 Server Key Exchange Message][2]
>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.

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

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

是吗?

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][2]
>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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

婴鹅 2025-01-13 05:53:05

在公钥加密中:

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

请参阅TLS 规范术语表

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

您不能使用私钥加密或使用公钥解密,这不是出于数学原因,而是因为它对于 加密

将普通语言或其他数据转换为代码;隐藏
通过将消息转换成某种形式来理解消息的含义
如果不知道秘密方法就无法解释
解释,称为关键;进行编码。

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

同样,您实际上并没有使用公钥签署某些内容。您只需要其中一把密钥即可进行签名,这就是私钥。您使用匹配的公钥验证签名。

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

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

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

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

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

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

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

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

虽然说“用证书签名”是一个常见的表达方式(如上所述),但我想说“使用公钥签名”肯定会令人困惑,因为“公钥”通常与“私钥”相对使用,并且它实际上是用于签名的私钥。尽管TLS 规范(第 F.1.1.2 节)< /a> 在一些地方谈到“使用证书签名”,“使用公钥签名”是一种不寻常且具有误导性的表达方式。

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

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

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

正如它放入 TLS 规范第 F.1.1.2 节< /a>:

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

你最后问的问题并不完全有意义:

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

公钥不用于验证服务器的身份。您可以验证您正在与服务器对话,该服务器的私钥与其之前提供的证书相匹配,因为它能够破译预主密钥并生成正确的完成消息。

编辑2:

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

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

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

为了更好地进行一般性理解,您应该首先尝试理解 Diffie-Hellman< /a> 及其 短暂变体(适用于 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 和/或替代名称)。这为您提供了客户端正在与之通信的服务器的身份。
  3. 主机名验证:仅仅知道您正在与向您提供对其有效的真实ID的人交谈是不够的,您还需要检查该名称是否与您想要连接的服务器相匹配。

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

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 public 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.

如日中天 2025-01-13 05:53:05

在 RSA 这样的 PPK 算法中,有两个不同的通信通道。使用公钥加密的信息仅对私钥的拥有者可读,并且使用私钥加密的信息仅对公钥的拥有者可读。

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

现在,实际上这并不重要;全世界都可以访问公钥,因此使用私有部分加密某些内容并不能保证其安全。但是您可以使用它进行身份验证:因为只有一个持有者拥有私钥,如果使用它对消息进行了有效加密,那么私钥持有者一定是作者。

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

In a PPK algorithm like RSA, you have two different communication channels. Information encrypted using the public key is only readable to the possessor of the private key, and information encrypted using the private key is only readable to the possessor of the public key.

In fact, the selection of which half of the pair is "public" is completely arbitrary.

Now, in practice this doesn't much matter; the whole world has access to the public key, so encrypting something with the private part wouldn't do anything to secure it. But you can use this for authentication: since only one holder has the private key, if a message is validly encrypted using it, then the private-key holder must have been the author.

That's why your book doesn't say that the private key is used for encryption: because it's used for integrity, not for confidentiality, as any message sealed using it would be readable to anyone possessing the non-secret public half. While the integrity validation mechanism is technically encryption (it is encipherment using modular exponentiation), it would be confusing to mention this in a foundations-of-cryptography context as it's not what people think when they hear "encryption" - they think "privacy".

枯叶蝶 2025-01-13 05:53:05

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

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

I had the same restlessness, since its difficult to ask without falling in technical holes. Quick, easy answer: regardless of the method details, yes, you could reverse engineer and decrypt from one key (is just math at the end) but because of the complexity of the operation, using a long value (you may use ie. a 4096-bit value) would make the reverse operation timeless, so you had to use either a machine so big that still doesnt exists or wait indefinitely, making it inviable... until someone comes up with a quick method to do it.

may want to take a look:
http://www.usna.edu/CS/si110arch/si110AY12F/lec/l29/lec.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文