【问题标题】:Indy SSL not working as expectedIndy SSL 未按预期工作
【发布时间】:2017-08-16 13:10:22
【问题描述】:

以下代码的工作原理如图所示,但不适用于注释掉的 URL。

你能看到我的错误吗?

var
  IdHTTP1: TIdHTTP;
  sl: TStringList;
  Src : string;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
begin
  try
    IdHTTP1 := TIdHTTP.Create(nil);
    try
      LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
      try
        IdHTTP1.IOHandler := LHandler;
        Src := IdHTTP1.Get(TIdURI.URLEncode(
          //'https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address=4600+Silver+Hill+Rd%2C+Suitland%2C+MD+20746&benchmark=9&format=json'
          'https://tools.usps.com/go/ZipLookupResultsAction!input.action?resultMode=0&companyName=&address1=1600+PENNSYLVANIA+AVE+NW&address2=&city=&state=Select&urbanCode=&postalCode=&zip=20500'
        ));
        ShowMessage(Copy(src, 1, 100));
      finally
        LHandler.Free;
      end;
    finally
      IdHTTP1.Free;
    end;
  except
    on E: Exception do
      ShowMessage('e');
  end;
  ShowMessage('done');
end;

注释掉的 URL 引发异常:

EIdOSSLUnderlyingCryptoError:连接 SSL 时出错。使用 SSL 连接时出错。错误:14094410:SSL 例程:SSL3_READ_BYTES:sslv3 警报握手失败

【问题讨论】:

  • “未按预期工作” - 那么您的预期是什么以及它实际上做了什么?
  • -.- 有什么例外? (提示:将showmessage('e') 更改为raise)。
  • EIdOSSLUnderlyingCryptoError:连接 SSL 时出错。使用 SSL 连接时出错。错误:14094410:SSL 例程:SSL3_READ_BYTES:sslv3 警报握手失败
  • 这表明阅读错误信息很重要。不要只是忽略它们的内容。它们通常包含有价值的信息。不收集事实,你怎么能指望调试呢?
  • 如果你是一名机械师,我把我的车带到你面前说“引擎有问题,请修理它”,你能猜到我的问题是引擎盖下的嘎嘎声吗?

标签: delphi idhttp


【解决方案1】:

您显示的两个 URL 已经 url 编码,因此您根本不应该将它们传递给 TIdURI.URLEncode(),只需将它们原样传递给 TIdHTTP.Get()。话虽如此,请确保您使用的是最新版本的 Indy,以便您拥有 this bug fix 以避免对任何已经进行百分比编码的序列进行双重编码。

无论如何,您遇到的问题与 URL 编码无关。 SSL 警报错误的原因是 TIdSSLIOHandlerSocketOpenSSL 默认仅启用 TLS 1.0,但许多现代 Web 服务器正在慢慢远离 TLS 1.0,现在需要 TLS 1.1+。 geocoding.geo.census.gov 不能使用低于 TLS 1.2 的任何东西,而 tools.usps.com 仍然允许 TLS 1.0。现代网络浏览器支持 TLS 1.0+。

因此解决方法是在TIdSSLIOHandlerSocketOpenSSL.SSLOptions.SSLVersions 属性1 中启用 TLS 1.1 和 TLS 1.2。

1:我在 Indy 的问题跟踪器中有 opened a ticket,以便在未来的版本中默认启用 TLS 1.1+。

【讨论】:

  • 1.不要同时分配MethodSSLVersions,分配一个或另一个。分配一个会自动为您更新另一个。 2. 如果您的 Indy 10 版本没有sslvTLSv1_2,那么您使用的是非常过时的版本并且需要升级,无论如何您都必须这样做才能支持最新的 OpenSSL。
  • @kualoa:您必须根据应用程序的编译方式(32 位或 64 位)使用正确的 OpenSSL 版本,而不是基于您运行的操作系统版本。您可以在 indy.fulgan.com/SSL 获得 Indy 的预编译 OpenSSL DLL
  • @kualoa:所有下载的文件名中都有 OpenSSL 版本号和平台名称。确定使用哪一个并不难——win32 用于 32 位,win64 用于 64 位。 Indy 支持的最新版本的 OpenSSL 是 1.0.2。 Fulgan 上提供的最新 DLL 用于 OpenSSL 1.0.2l(又名 1.0.2.12)。放置 DLL 的最佳位置是与应用的可执行文件位于同一文件夹中。
  • @kualoa:0.9.8 是 OpenSSL 的一个非常老的版本。您应该改用 1.0.2。无论如何,“未识别标识符”错误与您使用的 OpenSSL DLLS 版本无关,它与您使用的 Indy 版本有关。正如我之前告诉您的,“您使用的是非常过时的 [Indy] 版本,需要升级”。请download the latest version of Indy 10 并阅读Indy 10 Installation Instructions
猜你喜欢
  • 2012-03-05
  • 1970-01-01
  • 2021-06-04
  • 2022-01-24
  • 2015-05-11
  • 2020-05-15
  • 2014-10-31
  • 2018-02-12
  • 2014-01-20
相关资源
最近更新 更多