如果客户端已有服务器证书,SSL 握手/协议如何工作?
我对 SSL/TLS 协议和 OpenSSL 库的经验非常有限。本质上,我从本周开始学习它,但我对迄今为止学到的知识量感到自豪。
我确实有一个挥之不去的问题,但一直无法找到答案。我尝试过谷歌搜索并查看其他可用的资源,但似乎我不知道如何正确提出我的问题。它与握手过程有关,如果客户端已经拥有服务器证书会发生什么?
我知道握手的初始部分涉及以下高级步骤:
- 客户端发送问候消息
- 服务器用自己的问候消息进行响应
- 服务器发送证书
- 客户端验证服务器证书
- 服务器发送消息指示协商已完成
我似乎无法弄清楚当客户端已经拥有服务器证书时此过程将如何工作。我知道会话 ID 可用于恢复握手,其中仅发送 hello 消息,然后发送一条消息,说明此消息加密后的任何数据,从而避免在非对称握手中生成密钥。但使用这些会话 ID 对我来说似乎不是一个好主意,因为本质上它们必须持续很长时间,这可能会带来安全问题(我不知道如何,但拥有很长时间的持续时间似乎很糟糕)也许我错了)。我认为该行为可能类似于网络浏览器的行为,但未能找到该道路上的任何信息。
我查看了 OpenSSL API 做了一些研究,但也留下了一些挥之不去的问题。 API 方法:
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
当初始化/设置我的所有 OpenSSL 结构时,我认为这将是服务器证书文件(如果它已经存在)。但我做了进一步的研究,它可以用于客户端和服务器应用程序。那么,如果我是客户端并且没有服务器证书,那么在调用 SSL_connect() API 进行 SSL 握手之前,我是否会放弃使用上述 API 方法?我想如果是这种情况我也会以某种方式使用 OpenSSL API 来保存服务器证书?
感谢您阅读我的帖子。我感谢您提供的任何帮助/指导/指示。如果我的问题/想法不清楚,请告诉我,我会尽力澄清。
My experience with the SSL/TLS protocol and then OpenSSL library is very limited. Essentially I started learning about it this week, yet I feel proud of the amount of knowledge I have learned thus far.
I do have a lingering question though and haven't been able to find the answer. I've tried Googling it and looking into other resources available to me but it seems I don't know how to properly ask my question. It has to do with the handshake procedure and what happens if the client already has the server certificate?
I understand that the initial part of the handshake involves these high-level steps:
- Client sends hello message
- Server responds with its own hello message
- Server sends certificate
- Client verifies the server certificate
- Server sends message indicating that negotiation is done
I just can't seem to figure out how this procedure would work when the client already has the server certificate. I know that session ids can be used to do a resumed handshake where only the hello messages are sent and then a message stating any data after this message is encrypted, thus avoiding key generation in the asymmetric handshake. But using those session ids doesn't seem like a good idea to me as essentially they would have to last a very long long time which may pose security issues (I don't know how but it just seems bad to have a very long persisting session id. Maybe I am wrong through). I figured that the behavior may be similar to that of a web browser but failed to find any information on that road.
I went and looked at the OpenSSL API to do some research and it also left lingering questions. The API method:
int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
when initializing/setting up all my OpenSSL structs made me think that this would be the servers certificate file if it already existed. But I did further research and it can be used for both client and server applications. So in the case where I am a client and DON'T have the server certificate yet would I just forgo using the above API method before calling the SSL_connect() API to do the SSL handshake? I guess if this was the case I would somehow use the OpenSSL APIs to save the server certificate as well?
Thanks for reading my post. I appreciate any help/guidance/pointers you may be able to offer. If my questions/thoughts aren't clear please let me know and I will try to clarify them.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您似乎将缓存证书(“客户端已经拥有服务器证书”)与缓存连接状态(“避免在非对称握手中生成密钥”)混为一谈。
缓存服务器证书当然不存在安全问题。你如何获得该证书并不重要,因为它是完全公开的信息;它的目的是将服务器的公钥传达给您。无论您如何获取证书,只有当服务器具有相应的私钥时,密钥协商才会起作用。
但是,我不知道 OpenSSL API(或 SSL 协议)是否允许您假设您已经拥有服务器的证书并跳过握手的该部分。正如您已经了解的那样,您在客户端上调用 SSL_CTX_use_certificate_file() 来识别客户端证书。 Web 服务器将调用它来识别其自己的服务器证书。它不是用于识别客户端上的服务器证书,反之亦然。
至于重新使用现有的会话 ID(完全跳过密钥生成),这也非常安全。至少,这并不比拥有长期 SSL 连接更糟糕。如果有人发现了其中的问题,其结果将值得获得博士学位。至少。
[恢复会话的更新]
RFC 5246 第 7.3 节 提供了概述SSL 握手的过程,包括恢复会话的情况。恢复会话意味着您可以跳过交换和验证证书并直接跳到加密会话,从 ChangeCipherSpec 消息开始协商密钥。
顺便说一句,我认为在实践中恢复 SSL 会话并不常见。握手并不那么慢,而且保存状态很烦人。据我所知,Web 浏览器和服务器通常不使用此功能;他们只是在每个 SSL 连接上进行完整的握手。
You seem to be conflating caching the certificate ("client already has the server certificate") with caching the connection state ("avoiding key generation in the asymmetric handshake").
There is certainly no security issue with caching the server certificate. It does not matter how you get that certificate, because it is totally public information; its purpose is to convey the server's public key to you. The key negotiation will only work if the server has the corresponding private key, regardless of how you obtain the certificate.
However, I do not know whether the OpenSSL API (or the SSL protocol, for that matter) allows you to assume you already have the server's certificate and skip that part of the handshake. As you already figured out, SSL_CTX_use_certificate_file() is what you invoke on the client to identify the client certificate. And it is what a Web server would invoke to identify its own server certificate. It is not for identifying the server certificate on the client or vice-versa.
As for re-using an existing session ID (to skip key generation entirely), that is also plenty secure. At least, it is no worse than having a long-lived SSL connection. And if anybody discovered a problem with that, the result would be worth a Ph.D. at least.
[update on resuming sessions]
Section 7.3 of RFC 5246 has an overview of the SSL handshake, including the case where you resume a session. Resuming a session means you get to skip exchanging and verifying certificates and jump right into the encrypted session, starting with a ChangeCipherSpec message to negotiate the secret key.
Incidentally, I do not think it is common to resume SSL sessions in practice. The handshake is not that slow, and preserving the state is annoying. To my knowledge, Web browsers and servers do not generally use this feature; they just do the full handshake on every SSL connection.