2014-02-28 37 views
6

我用下面的代碼來設置SSLHandler用於POP3/SMTP發送/接收應用程序:如何使印OpenSSL的大多數服務器兼容

IdSSLHandler->SSLOptions->Mode  = sslmClient; 
IdSSLHandler->SSLOptions->Method  = slvSSLv23; 
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2; 

所以,上面的代碼應該支持SSL 3,TLS 1 ,TLS 1.1和TLS 1.2自動。這不起作用,並報告「錯誤的版本」錯誤。當SSLVersions行被刪除,然後它可以工作,但默認情況下,它包括我不想支持的sslvSSLv2。它是一樣的:

IdSSLHandler->SSLOptions->Mode  = sslmClient; 
IdSSLHandler->SSLOptions->Method  = slvSSLv23; 
IdSSLHandler->SSLOptions->SSLVersions = TIdSSLVersions() << sslvSSLv2 << sslvSSLv3 << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2; 

由於某種原因,這個工程和上述不在同一臺服務器上。我知道slvSSLv23是一種「使用任何可用版本」的值。那麼爲什麼它不適用於版本2不存在的上述代碼?

此外,我可以使用似乎被廣泛部署的TSL1,但如果服務器支持1.1或1.2,那麼我的代碼將不會使用更新的版本,但會強制1.0版本,除非使用上述類似的東西。

我想作一個初始化目標如下:

  • 所有的服務器兼容,不管他們使用的V3,TLS1,tls1.1或tls1.2
  • 自動使用最新的版本和使用較低的版本,如果更新的服務器上不可用但不低於版本3 - 如果版本低於3則失敗/異常

我認爲代碼的第一個版本會提供,但它報告版本錯誤。是否可以實現上述目標或者必須提供用戶設置才能選擇要使用的SSL版本?

+0

當你說「郵件」時,你在說什麼協議?使用'STARTTLS'的SMTP即使使用SSLv2也會受益,因爲機會式加密比沒有加密更好(而且我不是在寬鬆SSLv2)。但是,IMAPS或POP3S應使用TLSv1及更高版本,因爲客戶端將使用協議來檢查電子郵件和管理郵箱。 – jww

+0

我明白了,但我仍然希望避免使用SSL v2,因爲它已經過時,並且沒有多少服務器仍在使用它(我希望)。我已經更新了這個問題 - 它是POP3和SMTP。問題是上面的代碼不允許我似乎避免使用v2。 – Coder12345

回答

5

SSLVersions設置爲單個值會自動將Method設置爲相應的單個版本。將SSLVersions設置爲多個值會自動將Method設置爲slvSSLv23

Method設置爲單個版本會自動將SSLVersions設置爲相應的單個值。將Method設置爲slvSSLv23會自動將SSLVersions設置爲所有支持的值。

Indy根據MethodSSLVersions的值激活/禁用OpenSSL中相應的SSL_OP_NO_SSL_v#SSL_OP_NO_TLS_v#標誌。

我建議以下方法,這是因爲添加了新的TLS版本稍微面向未來:

IdSSLHandler->SSLOptions->Method  = sslvSSLv23; 
IdSSLHandler->SSLOptions->SSLVersions = IdSSLHandler->SSLOptions->SSLVersions >> sslvSSLv2; 

無論哪種方式,印將使用SSLv23只用SSL_OP_NO_SSL_v2標誌激活。

在該配置中,「錯誤版本」錯誤通常意味着服務器正在使用不支持版本協商的特定版本(它使用SSLv2兼容客戶端hello)。換句話說,連接到TLSv1服務器的SSLv23客戶端將會失敗。服務器必須使用SSLv23才能支持版本協商。在服務器上使用SSLv23允許它接受任何版本的客戶端,因爲客戶端啓動握手,因此服務器可以看到正在使用哪個版本頭。但是,在客戶端上使用SSLv23不允許它連接到除SSLv23服務器以外的任何服務器。 SSLv2服務器只能接受SSLv2客戶端,SSLv3服務器只能接受SSLv3客戶端,TLSv1服務器只能接受TLSv1客戶端等。

要真正連接到「任何」服務器,您必須檢測到「錯誤版本」錯誤,然後重新嘗試使用不同的特定Method/SSLVersions配置。不幸的是,「錯誤的版本」回覆不包括服務器的實際版本,所以你必須使用試錯法。如果SSLv23失敗,請嘗試TLSv1_2。如果失敗,請嘗試TLSv1_1。如果失敗,請嘗試TLSv1。如果失敗,請嘗試使用SSLv3。