OpenSSL让服务器和客户端协商该方法

Fra*_*ffa 4 ssl openssl

在一个非常过时的教程之后,我设法使用OpenSSL和TLS1.2创建了一个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);
Run Code Online (Sandbox Code Playgroud)

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

ssl = SSL_new(ssl_ctx);
SSL_set_fd(ssl, client_socket);
SSL_accept(ssl);
Run Code Online (Sandbox Code Playgroud)

所以我想在ssl_ctx创建中必须更改某些内容以允许更多方法...任何想法?

<rant> OpenSSL没有相当广泛的文档,最好的是10年的教程!</咆哮>

提前致谢.

rha*_*oto 11

您可以通过使用SSLv23_method() (和朋友)而不是特定方法(例如TLSv1_2_server_method()在您的示例中)来完成此操作.这将发送SSLv2 ClientHello,但也指定支持的最高协议.有点过时的手册页说:

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协议,但我在1.0.1g源代码中验证了s23_clnt.cSSLv23_method()包含它们.

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

稍后可以使用SSL_CTX_set_options()或SSL_set_options()函数的SSL_OP_NO_SSLv2,SSL_OP_NO_SSLv3,SSL_OP_NO_TLSv1选项限制可用协议列表.使用这些选项可以选择例如SSLv23_server_method()并且能够与所有可能的客户端协商,但只允许更新的协议,如SSLv3或TLSv1.

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

如果某些协议低于X,SSL_OP_NO_X将禁用X以上的所有协议.这是为了保持"版本能力"向量连续所必需的.因此,如果应用程序想要禁用TLS1.0而支持TLS1> = 1,则传递SSL_NO_TLSv1是不够的,答案是SSL_OP_NO_TLSv1 | SSL_OP_NO_SSLv3 | SSL_OP_NO_SSLv2.