2016-09-16 183 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版本嗎?謝謝。 –