如何在客户端支持多个版本的TLS?

6

你好,我想在客户端使用SSLV23方法支持多个版本的TLS。但是我无法连接,出现以下错误:

SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

请问有人能告诉我如何使用openssl支持多个版本的TLS吗?

SSLV23代码片段(不起作用):

cctx = SSL_CTX_new(SSLv23_client_method());
  if(cctx) {
  SSL_CTX_set_options(cctx, SSL_OP_NO_SSLv3);
  }

仅支持TLS V1(可用)

cctx = SSL_CTX_new(TLSv1_client_method());

你在什么上下文中使用它? - tadman
实际上,我们想在客户端禁用 SSLv3 并启用 TLS 协议,但如果我的服务器仅支持 TLS v1.2 或 TLS v1.1 或 TLS v1,我该如何在客户端提供该功能? - mahan07
为什么不直接使用 TLSv1_client_method() 呢?顺便说一下,你展示的代码在我的测试中确实导致了 TLS1.0 连接。 - Prabhu
1
使用SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3作为上下文选项。您应该使用SSL_OP_NO_COMPRESSION禁用压缩。由于您正在使用TLS 1.0及以上版本,因此还应设置SNI的服务器名称。另请参见OpenSSL维基上的SSL/TLS客户端 - jww
@Prabhu - "为什么不直接使用TLSv1_client_method()" - TLS 1.2是其中最安全的,所以最好不要排除它。 - jww
感谢@jww,你是救星,现在我能够使用代码cctx = SSL_CTX_new(SSLv23_client_method())支持所有三个TLS协议。 const long flags = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION; SSL_CTX_set_options(cctx, flags); - mahan07
1个回答

8

根据您的标签和评论,我认为您只想要TLS连接。客户端应该只发起TLS连接。如果是这样,为什么您还坚持使用SSLv23_client_method呢?但在我的测试中,以下内容确实发送了TLS 1.0客户端hello:

ctx = SSL_CTX_new(SSLv23_client_method());
SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv3);

为了防止POODLE攻击,最好的方法是在客户端和服务器上完全禁用SSL3支持。在您的情况下,您提到服务器仅支持TLS。因此,无需与SSL3上的客户端进行向后兼容。
如果服务器确实使用SSL3通信,则为了防止POODLE攻击,客户端和服务器应该实现TLS回退信令Cipher Suite Value-https://datatracker.ietf.org/doc/html/draft-ietf-tls-downgrade-scsv-05 以下是客户端设置TLS的示例:
/* Exclude SSLv2 and SSLv3 */
ctx = SSL_CTX_new(TLSv1_client_method());
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv3);

/* Exclude SSLv2, SSLv3 and TLS 1.0 */

 ctx = SSL_CTX_new(TLSv1_1_client_method());
 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
 SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv3);
 SSL_CTX_set_options(ctx,SSL_OP_NO_TLSv1);

/* Exclude SSLv2, SSLv3 ,TLS 1.0 and TLS 1.1 */

   ctx = SSL_CTX_new(TLSv1_2_client_method());
   SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
   SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv3);
   SSL_CTX_set_options(ctx,SSL_OP_NO_TLSv1);
   SSL_CTX_set_options(ctx,SSL_OP_NO_TLSv1_1);

您可以将选项进行OR运算,并一次性传递给SSL_CTX_set_options


你的回答可能会被误解为SSLv23_client_method()出现了问题。在OpenSSL 1.0.2中,它是一个通用的调用协议回退函数。你可以使用所有的SSL_OP_NO_*选项。请参阅手册 - reichhart
我同意@reichart的看法-这个答案在很大程度上是错误的。 TLSv1 * _client_method调用并不是Prabhu所想的那样。 它将协议锁定为TLS的那个版本。 你想要使用的是SSLv23_client_method(惊喜!),因为它会协商双方客户端和服务器支持的最佳方法。 默认情况下禁用SSLv2,因此您只需要禁用SSLv3。 换句话说,您需要与OP开始时完全相同的代码。 OP的代码中必须存在未列出的其他错误。 - Haydentech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接