【问题标题】:OpenSSL let the server and client negotiate the methodOpenSSL让服务器和客户端协商方法
【发布时间】:2014-07-05 18:08:14
【问题描述】:

按照一个非常过时的教程,我设法使用带有 TLS1.2 的 OpenSSL 创建了一个 HTTPS 服务器,我为此感到非常自豪;)

但是 TLS 1.2 仅在最新的浏览器中受支持,我希望在客户端和服务器之间进行某种协议协商,我确信可以完成,但我无法找到如何!因此,如果客户端仅支持 TLS1.0,请使用它。如果它只支持 SSLv3,请使用它。不确定 SSLv2,也许最好不要再说了……

我现在使用的代码是:

SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
ssl_method = TLSv1_2_server_method();
ssl_ctx = SSL_CTX_new(ssl_method);

然后加载服务器证书并在所有连接之间共享ssl_ctx。当客户端被服务器套接字accepted 时,它被封装在一个 SSL 对象中(无论它代表什么):

ssl = SSL_new(ssl_ctx);
SSL_set_fd(ssl, client_socket);
SSL_accept(ssl);

所以我猜想在创建 ssl_ctx 时必须进行一些更改以允许更多方法...有什么想法吗?

没有关于 OpenSSL 的像样的、广泛的文档,最好的是 10 年前的教程!

提前致谢。

【问题讨论】:

  • “没有像样的、广泛的 OpenSSL 文档......” - 是的,文档有时很糟糕。但是您应该查看来自 OpenSSL wiki 的 SSL/TLS Client

标签: ssl openssl


【解决方案1】:

您可以通过使用SSLv23_method()(和朋友)而不是特定方法(例如您的示例中的TLSv1_2_server_method())来做到这一点。这会发送 SSLv2 ClientHello,但也会指定支持的最高协议。有点过时的man page 说:

SSLv23_method(void), SSLv23_server_method(void), SSLv23_client_method(void)

使用这些方法建立的 TLS/SSL 连接将理解 SSLv2、SSLv3 和 TLSv1 协议。客户端将发送 SSLv2 客户端问候消息,并将表明它也理解 SSLv3 和 TLSv1。服务器将理解 SSLv2、SSLv3 和 TLSv1 客户端 你好消息。当兼容性很重要时,这是最佳选择 担心。

这个在线手册页没有讨论较新的 TLSv1_1 和 TLSv1_2 协议,但我在 s23_clnt.c 的 1.0.1g 源中验证了 SSLv23_method() 包含它们。

然后您可以使用SSL_CTX_set_options() 限制您实际接受的协议:

可用的协议列表稍后可以使用 SSL_OP_NO_SSLv2、SSL_OP_NO_SSLv3、SSL_OP_NO_TLSv1 选项 SSL_CTX_set_options() 或 SSL_set_options() 函数。使用这些 选项可以选择,例如SSLv23_server_method() 并成为 能够与所有可能的客户进行谈判,但只允许较新的客户 SSLv3 或 TLSv1 等协议。

但是请注意,您不能启用任意协议集,只能启用 SSLv2、SSLv3、TLSv1、TLSv1_1、TLSv1_2 中的连续协议。例如,您不能只选择 SSLv3 和 TLSv1_1,而忽略 TLSv1。来源中的这条评论解释了原因:

SSL_OP_NO_X 禁用所有高于 X 的协议 如果启用了低于 X 的一些协议。这是为了保持“版本能力”向量连续所必需的。因此,如果应用程序想要禁用 TLS1.0 以支持 TLS1>=1,则通过 SSL_NO_TLSv1 是不够的,答案是 SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-11-17
  • 2011-09-09
  • 1970-01-01
  • 2018-06-19
  • 2015-07-01
  • 2016-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多