【发布时间】: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。