【问题标题】:Indy 10 and sslvTLSv1_2Indy 10 和 sslvTLSv1_2
【发布时间】:2016-09-16 15:52:36
【问题描述】:

我有一个我发布到的网站,目前支持 TLS v1.1 和 TLS 1.2。他们很快将只允许 TLS ver 1.2 连接。为此,我将 Delphi 5 升级到了 Indy 10。

目前,我在代码中创建组件,每次运行 3 个线程时一切正常:

HTTp := TIdHttp.Create(nil);
      HTTP.OnSelectAuthorization := HTTPSelectAuthorization;
      HTTP.HTTPOptions := [hoInProcessAuth,hoForceEncodeParams,hoKeepOrigProtocol];

      HTTP.OnStatus := HTTPStatus;
      HTTP.OnWorkEnd := HTTPWorkEnd;
      HTTP.Request.ContentType := 'application/x-www-form-urlencoded';
      HTTP.ProxyParams.ProxyPort := ProxyPort;
      HTTP.ProxyParams.ProxyUsername := ProxyUserName;
      HTTP.ProxyParams.ProxyPassword := ProxyPassword;
      HTTP.ProxyParams.BasicAuthentication := ProxyBasicAuth;
    end;

    If UseSSL and (SSL = nil) then
    Begin
      SSL := TIDSSLIOHandlerSocketOpenSSL.Create(nil);
      SSL.SSLOptions.Mode := sslmClient;
      SSL.OnGetPassword := SSLGetPassword;
      SSL.SSLOptions.Method := sslvTLSv1_2;
      HTTP.IOHandler := SSL;
    end;

在发送帖子时,我是否会确切地告诉我当前实际连接的 TLS 版本?当他们最终停止接受 TLS v1.1 连接时,我不想让他们感到意外。

谢谢。

【问题讨论】:

  • sslvTLSv1_2 是否允许 v1.1 和 1.2,或仅允许 1.2?为了确保我会在 Internet 上搜索仅允许 1.2 的 HTTP 服务器并对其进行测试。
  • @mjn sslvTLSv1_2 仅代表 1.2。如果要同时支持 1.1 和 1.2,则需要使用 SSLOptions.SSLVersions 属性而不是 SSLOptions.Method 属性。这将允许您一次启用多个版本,以便 OpenSSL 可以执行版本协商以使用最高可用版本。
  • @RemyLabeau,你是说如果我使用 'SSL.SSLOptions.Method := sslvTLSv1_2' 来分配 SSL,如果该服务器不支持 TLS v1.2,我会收到错误消息并且Indy 不会自动尝试切换到 TLSv1_1?如果是这种情况,我不需要检查状态,对吗?

标签: delphi indy10 tls1.2


【解决方案1】:

没有专门为此目的举办的活动。您必须直接查询底层 SSL 对象,例如在 OnStatus 事件中,使用 SSL_get_version() 函数。

但是,您将 Method 专门设置为 TLS 1.2,所以这就是 Indy 将使用的全部内容(只要您使用支持 1.2 的 OpenSSL 版本,否则 Indy 将默默地回退到 1.0)。

附带说明,您的 UseSSL if 块应该看起来更像这样:

If UseSSL then
Begin
  If (SSL = nil) then
  Begin
    SSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    SSL.SSLOptions.Mode := sslmClient;
    SSL.OnGetPassword := SSLGetPassword;
    SSL.SSLOptions.Method := sslvTLSv1_2;
  End;
  HTTP.IOHandler := SSL;
end;

【讨论】:

  • 1.使用上面的代码,那不就是将 HTTP.IOHandler 分配为 nil 对吗?
  • @RobertGriffinrealsol 如果UseSSL 为真,我的示例总是将SSL 分配给IOHandler,如果SSL 尚不存在,则首先创建它。原代码中,如果SSL已经存在,当UseSSL为真时,不赋值给IOHandler
  • 2.我正在使用为 Indy 10 下载的 OpenSSL,因此我假设它支持 TLS v1.2。我认为这是正确的,因此是问题的原因。你能给我一个例子,如何使用 SSL_get_version() 以及在代码中实际放置它的位置。我用于发布的代码是 [HTTP.post(URL,ssSource,ssResult); HTTP.断开连接;]
【解决方案2】:

这是一个如何获取 SSL 版本信息的示例。 (可能需要一些更新,因为我不使用最新的 Indy)

声明

  procedure IdSSLIOHandlerSocketOpenSSLStatusInfoEx(ASender: TObject;
    const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType,
    AMsg: string);

分配

SSL.OnStatusInfoEx:=IdSSLIOHandlerSocketOpenSSLStatusInfoEx;

用法

procedure THttpThread.IdSSLIOHandlerSocketOpenSSLStatusInfoEx(ASender: TObject;
  const AsslSocket: PSSL; const AWhere, Aret: Integer; const AType,
  AMsg: string);
begin
  if AsslSocket.version = TLS1_VERSION then
    ...
end;

【讨论】:

  • 感谢您的代码示例。我试过了,但对 Indy 10 还不是很熟悉,它无法在 TSSL const 未知的情况下编译,而且从文档来看,StatusInfo 事件发生了一些变化。但有人告诉我,只要我在 Indy 10 中使用 'SSL.SSLOptions.Method := sslvTLSv1_2',它就只使用 sslvTLSv1_2。所以我只是假设这就是我在向我发送到的 3 个站点发送帖子时的连接方式。如果主机不支持 sslvTLSv1_2,我想我会遇到某种异常。
  • 您必须将IdSSLOpenSSLHeaders 单元添加到您的项目uses 部分。
  • 感谢代码,但即使将 IdSSLOpenSSLHeaders 添加到使用子句并分配 SSL.OnStatusInfoEx:=IdSSLIOHandlerSocketOpenSSLStatusInfoEx;,IdSSLIOHandlerSocketOpenSSLStatusInfoEx 也永远不会被调用。我使事件变得简单以便测试,并添加了一个 Break 以便 IDE 在遇到事件时停止,但事件从未触发。您能想到的任何其他方式将显示软件在连接时使用的 TLS 版本?谢谢。
  • 你肯定做错了什么。创建一个新项目,在设计时创建TIdHTTPTIdSSLIOHandlerSocketOpenSSL,在设计时分配IOHandler和OnStatusInfoEx事件,添加OpenSSL库并运行(任意按钮获取HTTPS页面)。 100% 有效
  • 好吧,它可以编译,但如果事件被触发,我添加了一条调试消息,从不显示。所以,从 IDE 中跑了出来。从不开火。必须在 Indy 10 中设置其他内容才能触发此事件。这就是我所缺少的。
猜你喜欢
  • 2013-04-28
  • 1970-01-01
  • 1970-01-01
  • 2014-09-21
  • 1970-01-01
  • 2015-09-14
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多