簡體   English   中英

HttpClient支持多種TLS協議

[英]HttpClient supporting multiple TLS protocols

我們正在編寫一個必須使用HTTPS與幾台服務器通信的應用程序。 它需要與AWS(使用AWS庫)以及使用TLS 1.2的一些內部服務進行通信。

我開始通過更改我的HttpClient來使用TLS 1.2 SSLContext:

public static SchemeRegistry buildSchemeRegistry() throws Exception {
    final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(createKeyManager(), createTrustManager(), new SecureRandom());
    final SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("https", 443, new SSLSocketFactory(sslContext)));
    return schemeRegistry;
}

並將此SchemeRegistry注入到DefaultHttpClient對象中(通過spring),但這樣做我從AWS獲得錯誤,因此我假設(我可能錯了)AWS不支持TLS 1.2(如果我只是,我不會收到此消息使用正常的DefaultHttpClient):

AmazonServiceException: Status Code: 403, AWS Service: AmazonSimpleDB, AWS Request ID: 5d91d65f-7158-91b6-431d-56e1c76a844c, AWS Error Code: InvalidClientTokenId, AWS Error Message: The AWS Access Key Id you provided does not exist in our records.

如果我嘗試在spring中定義兩個HttpClient,一個使用TLS 1.2,一個是默認值,我得到以下錯誤,我認為這意味着Spring不喜歡實例化並自動裝配兩個HttpClient對象:

SEVERE: Servlet /my-refsvc threw load() exception
java.lang.NullPointerException
at com.company.project.refsvc.base.HttpsClientFactory.<clinit>(BentoHttpsClientFactory.java:25)
...
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1031)
at 
...
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)

我沒有在java中使用過多的HTTPS,所以請問有什么人給我一些建議嗎? 1)我如何讓Spring允許兩個HttpClient對象,一個連接到AWS東西bean,另一個連接到其他bean以訪問TLS1.2服務2)或者是否可以更改一個HttpClient對象能夠嘗試TLS1.2(通過SSLContext,或SchemeRegistry或其他東西),如果失敗,那么嘗試TLS1.1或1.0? 3)如果兩者都有可能,那么“更好”的做法是什么?

TLS有一個內置機制來協商使用哪個版本的協議。 來自RFC 5246(附錄E)

TLS版本1.0,1.1和1.2以及SSL 3.0非常相似,並使用兼容的ClientHello消息; 因此,支持所有這些相對容易。 同樣,只要ClientHello格式保持兼容,服務器就可以輕松處理嘗試使用未來版本TLS的客戶端,並且客戶端支持服務器中可用的最高協議版本。

希望與此類舊服務器協商的TLS 1.2客戶端將在ClientHello.client_version中發送包含{3,3}(TLS 1.2)的普通TLS 1.2 ClientHello。 如果服務器不支持此版本,它將使用包含舊版本號的ServerHello進行響應。 如果客戶同意使用此版本,則協商將根據協商協議進行。

此外,更改SSLContext.getInstance(...)的版本號僅會更改默認情況下啟用協議。 使用SSLSocket.setEnabledProtocols(...)設置實際協議版本(請參閱此問題 )。 我不確定你正在使用的其他庫,但它可能會在某處設置啟用的協議。

有幾種可能性:

  • 您在createKeyManager()所做的事情與默認行為不同。 如果服務使用客戶端證書身份驗證,配置錯誤肯定會導致403錯誤。

  • (不太可能,我猜,但很難說沒有看到你的createKeyManager()createTrustManager() )。 您使用的服務器可能與TLS 1.2和版本協商機制不兼容。 sun.security.ssl.SSLContextImpl有此評論:

    SSL / TLS協議指定了前向兼容性和版本回滾攻擊保護,但是,許多SSL / TLS服務器供應商沒有正確實現這些方面,並且一些當前的SSL / TLS服務器可能拒絕與TLS 1.1或更高版本通信客戶。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM