Delphi XE + Indy 10.6.2.0:TLS v1.2 挂起 IdSMTP.Connect;

Delphi XE + Indy 10.6.2.0: TLS v1.2 hangs on IdSMTP.Connect;

当尝试使用 TLS v1.2 方法和端口 465 连接到 SMTP 服务器时,我的程序无限挂起。我在 mailbox.org(必须使用 TLS 1.2)上创建了一个测试邮件帐户,并尝试使用提供的数据。

环境:Delphi XE、Indy 10.6.2、程序文件夹中的 OpenSSL 1.0.2u DLL 文件。

源代码:

try
   IdSMTPReport.IOHandler := FormMain.IdSSLIOHandlerSocketMail;
   IdSMTPReport.UseTLS := utUseExplicitTLS;
   IdSSLIOHandlerSocketMail.SSLOptions.Method := sslvTLSv1_2;

   IdSMTPReport.Host := ###;
   IdSMTPReport.Username := ###;
   IdSMTPReport.Password := ###;
   IdSMTPReport.Port := 465;

   IdMessageReport.ContentType := 'text/plain; charset=UTF-8';
   IdMessageReport.Sender.Address := IdMessageReport.From.Address;
   IdMessageReport.Sender.Name := IdMessageReport.From.Name;
   IdMessageReport.Recipients.Clear;
   IdMessageReport.Recipients.EMailAddresses := ###;
   IdMessageReport.Subject := 'Test';
   IdMessageReport.Body.Clear;
   IdMessageReport.Body := MailReport;
   IdSMTPReport.Connect;
   IdSMTPReport.Send(IdMessageReport);
   IdSMTPReport.Disconnect;
except
   try
      IdSMTPReport.Disconnect;
   except
   end;
end;

对象检查器中的 IdSSLIOHandlerSocketMail 设置

它在向 OnStatus/OnStatusInfo 事件发送任何状态 text/info 消息之前挂起。

SMTP 服务器使用给定的凭据工作正常。如果我尝试使用 TLS 1.2 和端口 587 的另一台服务器(1und1,德国 ISP),它工作正常。如果我更改为端口 465,10000 毫秒的超时(即使有更高的超时)在没有发送邮件的情况下生效:

状态信息:

Resolving hostname ###
Connecting to ###
Connected.
-> Timeout
Disconnected.

有什么想法吗?

您正在将 TIdSMTP.UseTLS 属性 设置为 utUseExplicitTLS。这意味着 TIdSMTP 将以最初未加密的状态连接到服务器,读取服务器的问候语和功能,然后发送 STARTTLS 命令以请求允许发送 TLS 握手以启动新的加密会话。

但是,端口 465 是 SMTP 的隐式 TLS 端口。这意味着服务器将期望客户端在连接后立即执行 TLS 握手,然后再交换任何 SMTP 数据,包括服务器的问候语。

因此,由于使用了错误的配置,您陷入了第 22 条军规。通过使用utUseExplicitTLSTIdSMTP正在等待服务器未加密的问候语。但是,通过使用端口 465,服务器正在等待客户端的 TLS 握手。所以双方都没有满足对方的等待条件,因此超时。

SMTP 的 explicit TLS 端口改为 587。所以,你需要:

  • 在端口 465 上使用 utUseImplicitTLS

  • 在端口 587 上使用 utUseExplicitTLS

除非服务器配置不同。