java – 支持多种TLS协议的HttpClient

前端之家收集整理的这篇文章主要介绍了java – 支持多种TLS协议的HttpClient前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我们正在编写一个必须使用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.beanfactory.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 (Appendix E)开始:

TLS versions 1.0,1.1,and 1.2,and SSL 3.0 are very similar,and
use compatible ClientHello messages; thus,supporting all of them
is relatively easy. Similarly,servers can easily handle clients
trying to use future versions of TLS as long as the ClientHello
format remains compatible,and the client supports the highest
protocol version available in the server.

A TLS 1.2 client who wishes to negotiate with such older servers
will send a normal TLS 1.2 ClientHello,containing { 3,3 } (TLS
1.2) in ClientHello.client_version. If the server does not support this version,it will respond with a ServerHello containing an
older version number. If the client agrees to use this version,
the negotiation will proceed as appropriate for the negotiated
protocol.

此外,更改SSLContext.getInstance(…)中的版本号仅会更改默认情况下启用的协议.设置实际协议版本的方法是使用SSLSocket.setEnabledProtocols(...)(参见this question).我不确定你正在使用的其他库,但它可能会在某处设置启用的协议.

有几种可能性:

>您在createKeyManager()中执行的操作与默认行为不同.如果服务使用客户端证书身份验证,配置错误肯定会导致403错误.
>(不太可能,我猜,但很难说没有看到你的createKeyManager()和createTrustManager()).您使用的服务器可能与TLS 1.2和版本协商机制不兼容. sun.security.ssl.SSLContextImpl中有此评论

SSL/TLS protocols specify the forward compatibility and version
roll-back attack protections,however,a number of SSL/TLS server
vendors did not implement these aspects properly,and some current
SSL/TLS servers may refuse to talk to a TLS 1.1 or later client.

猜你在找的Spring相关文章