2016-09-16 172 views
0

我有一个网站,我发布到目前支持TLS v1.1和TLS 1.2。他们很快只会允许TLS 1.2版本的连接。出于这个原因,我将Delphi 5升级到了Indy 10。Indy 10和sslvTLSv1_2

目前,我在代码中创建我的组件和一切伟大工程同时运行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连接时,我不希望有什么惊喜。

谢谢。

+0

不sslvTLSv1_2允许v1.1和1.2 ,还是只有1.2?为了确保我会在Internet上搜索一个只允许1.2的HTTP服务器并对其进行测试。 – mjn

+0

@mjn'sslvTLSv1_2'只代表1.2。如果你想同时支持1.1和1.2,你需要使用'SSLOptions.SSLVersions'属性来代替'SSLOptions.Method'属性。这将允许您一次启用多个版本,因此OpenSSL可以执行版本协商以使用最高版本。 –

+0

@RemyLabeau,你是说如果我使用'SSL.SSLOptions.Method:= sslvTLSv1_2'来分配SSL,如果该服务器不支持TLS v1.2,我会得到一个错误,Indy不会自动尝试切换到TLSv1_1?如果是这种情况,我不需要检查状态,对不对? –

回答

1

没有特别为此目的的事件。您将不得不使用SSL_get_version()函数直接查询底层SSL对象,例如在OnStatus事件中。

但是,您将Method专门设置为TLS 1.2,因此Indy将使用所有(只要您使用支持1.2的OpenSSL版本,否则Indy将默默回退到1.0)。

在一个侧面说明,你UseSSL如果块应该看起来更像是这样的:

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; 
+0

1.使用上面的代码,这不就是将HTTP.IOHandler分配为零,正确吗? –

+1

@RobertGriffinrealsol如果UseSSL为true,我的示例总是将'SSL'分配给'IOHandler',如果它还不存在,则首先创建'SSL'。在原始代码中,如果'SSL' * already *存在,则当'UseSSL'为true时,它不会被分配给'IOHandler'。 –

+0

2.我使用的是我为Indy 10下载的OpenSSL,所以我假设它支持TLS v1.2。我认为这是正确的,因此问题的原因。你可以给我一个例子,说明如何使用SSL_get_version()以及将代码实际放在哪里。我用于发布的代码是[HTTP.post(URL,ssSource,ssResult); HTTP.Disconnect;] –

0

下面是一个例子,你如何能得到有关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; 
+0

感谢您的代码示例。我尝试了它,并且还没有熟悉Indy 10,它无法编译TSSL常量未知,并且从文档中看出StatusInfo事​​件改变了一些。但是我被告知,只要我在Indy 10中使用'SSL.SSLOptions.Method:= sslvTLSv1_2',它只使用sslvTLSv1_2。所以我只是假设我发送帖子到我发送给3个网站时的连接方式。我想如果主机不支持sslvTLSv1_2,我会得到某种异常。 –

+0

您必须将'IdSSLOpenSSLHeaders'单元添加到您的项目'用途'部分。 – smooty86

+0

感谢您的代码,但即使将IdSSLOpenSSLHeaders添加到uses子句并分配SSL.OnStatusInfoEx:= IdSSLIOHandlerSocketOpenSSLStatusInfoEx,IdSSLIOHandlerSocketOpenSSLStatusInfoEx也不会被调用。我将事件简化为测试,并添加了一个Break,以便在遇到事件时IDE停止,但事件从未解除。你能想到的任何其他方式都会显示软件在连接时使用的TLS版本吗?谢谢。 –