【问题标题】:ssl v3 poodle and move to tls with indyssl v3 poodle 并使用 indy 移动到 tls
【发布时间】:2014-12-15 15:35:05
【问题描述】:

如您所知,新的poodle 已经上线,Witch barks 让Twitter, Cloudflare 放弃对 SSL3 的支持。

Indy(TidHttp) 10.6.0.0 恢复了这个不错的例外:

EidOsslUnerlayingCryptoError 消息“与 SSL 连接时出错。 错误:14094410:SSL 例程:SSL3_READ_BYTES:sslv3 警报握手 失败'

我的问题是处理 TLS 所需的定义是什么?

更新: 这是引发异常的代码:完整的工作代码。

var
  parameters:TStringList;
  keySecretBase64:string;
  stream:TStringStream;
  IdEncoderMIME1 : TIdEncoderMIME;
  idHttp1 : TIdHTTP;
  IdSSLIOHandlerSocketOpenSSL1:TIdSSLIOHandlerSocketOpenSSL;//assume on Form
begin
  stream:=TStringStream.create;
  parameters:=TStringList.Create;
  IdEncoderMIME1 := TIdEncoderMIME.Create(nil);
  idHttp1 := TIdHTTP.Create(nil);
  IdSSLIOHandlerSocketOpenSSL1:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1_2;
  IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];
    with IdSSLIOHandlerSocketOpenSSL1 do begin
      SSLOptions.Method := sslvSSLv3;
      SSLOptions.Mode :=  sslmUnassigned;
      SSLOptions.VerifyMode := [];
      SSLOptions.VerifyDepth := 2;
    end;
    with idHttp1 do begin
      IOHandler := IdSSLIOHandlerSocketOpenSSL1;
      ReadTimeout := 0;
      AllowCookies := True;
      ProxyParams.BasicAuthentication := False;
      ProxyParams.ProxyPort := 0;
      Request.ContentLength := -1;
      Request.ContentRangeEnd := 0;
      Request.ContentRangeStart := 0;
      Request.ContentType := 'application/x-www-form-urlencoded';
      Request.Accept := 'text/html, */*';

      Request.BasicAuthentication := False;
      Request.UserAgent := 'Mozilla/3.0 (compatible; Indy Library)';
      HTTPOptions := [hoForceEncodeParams];
    end;
    parameters.Clear;
    idHttp1.Request.CustomHeaders.Clear;
    IdEncoderMIME1.FillChar:='=';

  try
    keySecretBase64 := TIdEncoderMIME.EncodeString(key+ ':' + secret, IndyTextEncoding_UTF8);// this is twitter provided key and secret
    parameters.Add('grant_type=client_credentials');
    idHttp1.Request.CustomHeaders.AddValue('Authorization','Basic '+keySecretBase64);
    idHttp1.post(URL,parameters,stream);
  finally
    stream.Free;
    parameters.Free;
    parameters.Free;
    IdSSLIOHandlerSocketOpenSSL1.Free;
  end;
end;

【问题讨论】:

  • 您仅使用 TLSv1 连接,因此您只能使用 SSLv23 通配符或专门使用 TLSv1 连接到服务器,否则您的 TLSv1 握手将失败。
  • 您的示例代码可能要短得多 - 只需 IdHttp.Get('https://www.google.com') 或不同的 https 地址和 SSLIOHandler 部分是必需的
  • 真的。然而,据我所知,谷歌并不否认 ssl 和强制 tls,请查看关于 twitter 和 cloudflare 的第二个链接。
  • @MSchenkel:在 Indy 10.6 中,TIdTextEncoding 类被替换为新的 IIdTextEncoding 接口。见this blog article
  • @mjn:如果您考虑到TIdHTTP 现在可以创建自己的SSLIOHandler(默认为 TLSv1),则代码可以进一步缩短,如果尚未分配,请求 HTTPS 网址时。见this blog article

标签: delphi ssl indy


【解决方案1】:

您的代码在 SSLOptions 属性 Method 中选择 TLS 1.2

IdSSLIOHandlerSocketOpenSSL1.SSLOptions.Method := sslvTLSv1_2;
IdSSLIOHandlerSocketOpenSSL1.SSLOptions.SSLVersions := [sslvTLSv1_2];

但是,两行之后这个值被SSL 3覆盖:

with IdSSLIOHandlerSocketOpenSSL1 do begin
  SSLOptions.Method := sslvSSLv3;
  ...
end;

因此客户端不会使用更新的 TLS 1.2 协议而是使用 SSL 3 进行连接,服务器不再支持该协议。

这解释了错误消息,它表示 SSL 3 握手(客户端尝试)失败:

SSL。错误:14094410:SSL 例程:SSL3_READ_BYTES:sslv3 警报握手 失败'

如果您删除第二个分配,IdHTTP 客户端将使用 TLS 1.2 进行连接。

【讨论】:

  • 你确实解决了这个问题,但是现在有一个“Soket Error #10054 connection reset by peer”,它没有建立 tls 连接。原因码不完整。
【解决方案2】:

SSL2、SSL3 和 TLS1.0 都容易受到中间人攻击。您应该使用 TLS 1.1 及更高版本进行安全连接。不幸的是,Indy 9 不支持 TLS 1.1 及更高版本。

This answer 报告在 Indy 10 中有一个选项 TLSv1_2 用于 TLS 1.2,但在 Indy 10 online documentation 中没有提供。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2016-02-28
    • 1970-01-01
    • 2012-05-04
    • 2020-09-15
    • 2015-04-21
    • 2014-12-11
    相关资源
    最近更新 更多