如何使 Indy OpenSSL 与大多数服务器兼容 [英] How to make Indy OpenSSL compatible with most servers

查看:17
本文介绍了如何使 Indy OpenSSL 与大多数服务器兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码为 POP3/SMTP 发送/接收应用程序设置 SSLHandler:

I use the following code to setup SSLHandler for POP3/SMTP sending/receiving app:

IdSSLHandler->SSLOptions->Mode        = sslmClient;
IdSSLHandler->SSLOptions->Method      = slvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;

因此,上面的代码应该自动支持 SSL 3、TLS 1、TLS 1.1 和 TLS 1.2.这不能很好地工作并报告错误版本"错误.当删除 SSLVersions 行时,它可以工作,但默认情况下它包含我不想支持的 sslvSSLv2.它是一样的:

So, the above code is supposed to support SSL 3, TLS 1, TLS 1.1 and TLS 1.2 automatically. This does not work well and reports "wrong version" error. When the SSLVersions line is removed then it works but by defaults it includes sslvSSLv2 which I don't want to support. It is the same like:

IdSSLHandler->SSLOptions->Mode        = sslmClient;
IdSSLHandler->SSLOptions->Method      = slvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv2 << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;

出于某种原因,这有效,而上述内容不在同一台服务器上.我知道 slvSSLv23 是一种使用任何可用版本"的值.那么为什么它不适用于上面没有版本 2 的代码?

For some reason, this works and the above does not on same server. I know that slvSSLv23 is a kind of "use any available version" value. So why does it not work with above code where version 2 is not present?

此外,我可以使用似乎广泛部署的 TSL1,但如果服务器支持 1.1 或 1.2,那么我的代码将不会使用更新的版本,但会强制使用 1.0 版本,除非使用上述内容.

Additionally, I can use TSL1 which seems to be widely deployed, but if the server supports 1.1 or 1.2 then my code won't be using more recent versions but will force 1.0 version unless something like above is used.

我想用以下目标进行初始化:

I would like to make an initialization with the following goals:

  • 与所有服务器兼容,无论它们使用 v3、tls1、tls1.1 还是 tls1.2
  • 如果服务器上没有最新版本但不低于版本 3,则自动使用最新版本并使用较低版本 - 如果版本低于 3,则失败/异常

我认为代码的第一个版本会提供,但它报告版本错误.上述目标是否可能或必须提供用户设置来选择要使用的 SSL 版本?

I thought the first version of the code would provide that but it reports version error. Are the above goals possible or a user-setting must be provided to select SSL version to use?

推荐答案

SSLVersions 设置为单个值会自动将 Method 设置为相应的单个版本.将 SSLVersions 设置为多个值会自动将 Method 设置为 slvSSLv23.

Setting the SSLVersions to a single value automatically sets the Method to the corresponding single version. Setting the SSLVersions to multiple values automatically sets the Method to slvSSLv23.

Method 设置为单个版本会自动将 SSLVersions 设置为相应的单个值.将 Method 设置为 slvSSLv23 会自动将 SSLVersions 设置为所有支持的值.

Setting the Method to a single version automatically sets the SSLVersions to the corresponding single value. Setting the Method to slvSSLv23 automatically sets the SSLVersions to all supported values.

Indy 根据 MethodSSLVersions.

Indy activates/deactivates the appropriate SSL_OP_NO_SSL_v# and SSL_OP_NO_TLS_v# flags in OpenSSL depending on the values of Method and SSLVersions.

我建议采用以下方法,随着新 TLS 版本的添加,这种方法更具前瞻性:

I would suggest the following approach, which is a slightly more future proof as new TLS versions are added:

IdSSLHandler->SSLOptions->Method      = sslvSSLv23;
IdSSLHandler->SSLOptions->SSLVersions = IdSSLHandler->SSLOptions->SSLVersions >> sslvSSLv2;

无论哪种方式,Indy 都将使用 SSLv23,并且仅激活 SSL_OP_NO_SSL_v2 标志.

Either way, Indy would be using SSLv23 with only the SSL_OP_NO_SSL_v2 flag activated.

在该配置中,错误版本"错误通常意味着服务器正在使用不支持版本协商的特定版本(使用与 SSLv2 兼容的客户端 hello).换句话说,连接到 TLSv1 服务器的 SSLv23 客户端将失败.服务器必须使用 SSLv23 才能支持版本协商.在服务器上使用 SSLv23 允许它接受任何版本的客户端,因为客户端启动握手,因此服务器可以查看正在使用的版本标头.但是在客户端上使用 SSLv23 不允许它连接到除 SSLv23 服务器之外的任何服务器.SSLv2服务器只能接受SSLv2客户端,SSLv3服务器只能接受SSLv3客户端,TLSv1服务器只能接受TLSv1客户端,以此类推.

In that configuration, a "wrong version" error typically means the server is using a specific version that does not support version negotiation (which uses an SSLv2-compatible client hello). In other words, an SSLv23 client connecting to a TLSv1 server will fail. The server must use SSLv23 in order to support version negotiation. Using SSLv23 on the server allows it to accept any version client, as the client initiates the handshake so the server can see which version header is being used. But using SSLv23 on the client DOES NOT allow it to connect to any server OTHER THAN an SSLv23 server. An SSLv2 server can only accept SSLv2 clients, an SSLv3 server can only accept SSLv3 clients, a TLSv1 server can only accept TLSv1 clients, and so on.

要真正连接到任何"服务器,您必须检测错误版本"错误并使用不同的特定Method/SSLVersions 配置重试.不幸的是,错误版本"回复不包括服务器的实际版本,因此您必须使用试错法.如果 SSLv23 失败,请尝试 TLSv1_2.如果失败,请尝试 TLSv1_1.如果失败,请尝试 TLSv1.如果失败,请尝试 SSLv3.

To truly connect to "any" server, you would have to detect a "wrong version" error and retry with a different specific Method/SSLVersions configuration. Unfortunately, the "wrong version" reply does not include the server's actual version, so you have to use trial-and-error. If SSLv23 fails, try TLSv1_2. If that fails, try TLSv1_1. If that fails, try TLSv1. If that fails, try SSLv3.

这篇关于如何使 Indy OpenSSL 与大多数服务器兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆