【问题标题】:Delphi Indy SSL Error after migrating to 10.4 Sydney迁移到 10.4 悉尼后的 Delphi Indy SSL 错误
【发布时间】:2020-09-15 23:52:27
【问题描述】:

在使用 Delphi 10.4 编译我的 win32 客户端/服务器应用程序(使用 INDY 和 TMS Sparkle)后,我收到一个 ssl 错误。我在服务器端使用 Indy 和自签名证书,在客户端使用 indy。错误信息是(从德语翻译):

与 SSL 的连接错误。 EOF 遇到了违反协议的情况。

我没有从 10.3 更改它运行完美的任何代码或环境。我可以将它分解到服务器端,因为旧服务器(在 10.3 中编译)与新客户端(使用 10.4 编译)一起运行,但旧客户端在尝试连接到新服务器时也会中断。

这就是我初始化 SSL 的方式:

    SecureServer := TIndySparkleHTTPServer.create(nil);
    SecureServer.DefaultPort := SecurePort;
    // Initialize SSL with self signed certificate
    SSLHandler := TIdServerIOHandlerSSLOpenSSL.create(SecureServer);
    SSLHandler.SSLOptions.CertFile := SharedVals.ServerPath + 'appcert.pem';
    SSLHandler.SSLOptions.RootCertFile := SharedVals.ServerPath + 'approot.pem';
    SSLHandler.SSLOptions.KeyFile := SharedVals.ServerPath + 'appkey.pem';
    SSLHandler.SSLOptions.Method := sslvSSLv23;
    SecureServer.IOHandler := SSLHandler;

Emba 在 10.3 中成功破解了 Indy,也许这是另一种类似的情况?

【问题讨论】:

  • EOF encountered violating the protocol 表示服务器在 SSL/TLS 握手过程中关闭 TCP 连接。如果服务器不喜欢握手中的某些内容,通常会发生这种情况,但 OpenSSL通常会在关闭连接之前向客户端发送警报。您是否在客户端连接后检查您的服务器是否引发未捕获的异常?附带说明一下,您根本不应该使用SSLOptions.Method 属性,而是使用SSLOptions.SSLVersions 属性,例如SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
  • Embarcadero 确实在 10.3 中破坏了 Indy 中的 OpenSSL 支持,但他们修复了它,几周前他们刚刚为 10.4 获取了最新的 Indy,并且 AFAIK 没有已知问题 TIdHTTPServer 或其在最新的 Indy 中使用 OpenSSL。
  • 谢谢,我调试了服务器,确实我得到了带有“Fehler bei der Analyze einer Anweisung”的 EIdHttpErrorParsindCommand,这意味着类似于“错误解析命令”我不知道并认为 Irollback 到 D10.3。 ..
  • EIdHTTPErrorParsingCommandTIdHTTPServer 收到格式错误的 HTTP 请求时引发。由于TIdHTTPServer 直到首先完成 SSL/TLS 握手后才处理解密的 HTTPS 请求,这意味着您的服务器实际上根本没有尝试执行 SSL/TLS 握手,因此是试图解析客户端的 SSL/TLS 握手请求,就好像它是一个 HTTP 请求一样。您的 SecurePort 是否设置为非标准 HTTPS 端口(443 以外的端口)?如果是这样,请确保您的服务器有一个 OnQuerySSLPort 事件处理程序,该处理程序为该端口返回 VUseSSL=True
  • 雷米:再次感谢。我一直在使用非标准端口,它似乎可以通过使用一个小的帮助程序类将 vUseSSL 设置为 true 来工作。对我来说,似乎 10.4 在这里并没有默默地默认为 true,而 10.3 却是这样。我看到这种非默认端口行为已经在 2018 年的 Indy 中引入(Atozed Change log)。

标签: delphi ssl indy


【解决方案1】:

感谢 Remy Lebau,他为我指明了正确的方向。但是我想通过提供使它在 Delphi 10.4 中再次工作的代码来回答我的问题。由于 Indy 的更改是在 2018 年完成的(!)我仍然不知道为什么它在 10.3 中完美运行,直到升级到 10.4。

由于我直接在服务/守护程序项目中使用 TMS Sparke Server for Indy,因此我提供了一个小类来连接需要对象方法的 OnQuerySSLPort 方法。

type
  TSSLHelper = class
  // This helper class is neccessary to set ssl true
  // as it defaults to false on non standard ssl ports
    procedure QuerySSLPort(APort: Word; var VUseSSL: boolean);
  end;

...

procedure TSSLHelper.QuerySSLPort(APort: Word; var VUseSSL: boolean);
begin
  VUseSSL := true;
end;

...

SecureServer := TIndySparkleHTTPServer.create(nil);
SecureServer.DefaultPort := SecurePort;
// Initialize SSL with self signed certificate
SSLHandler := TIdServerIOHandlerSSLOpenSSL.create(SecureServer);
SSLHandler.SSLOptions.CertFile := SharedVals.ServerPath + 'appcert.pem';
SSLHandler.SSLOptions.RootCertFile := SharedVals.ServerPath + 'approot.pem';
SSLHandler.SSLOptions.KeyFile := SharedVals.ServerPath + 'appkey.pem';
SSLHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
SecureServer.IOHandler := SSLHandler;
SSLHelper := TSSLHelper.Create;
SecureServer.OnQuerySSLPort := SSLHelper.QuerySSLPort;
...

现在它像以前一样工作了。

【讨论】:

  • 谢谢。刚刚花了 5 个小时试图调试为什么我的应用程序在从里约热内卢搬到悉尼后停止工作。谷歌 30 秒发现了这个问题并进行了修复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多