繁体   English   中英

使用jersey-apache-client-1.18的SSL handshake_failure

[英]SSL handshake_failure using jersey-apache-client-1.18

我正在使用jersey-apache-client进行ssl连接。在验证连接时收到握手错误。 以下是握手错误。

WRITE: TLSv1 Change Cipher Spec, length = 1
Finished
verify_data:  { 165, 117, 49, 237, 116, 71, 111, 175, 161, 237, 45, 30 }
WRITE: TLSv1 Handshake, length = 48
READ: TLSv1 Alert, length = 2
RECV TLSv1 ALERT:  fatal, handshake_failure
%% Invalidated:  [Session-1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA]

如果使用jersey-client-1.13并且未收到握手错误,该代码将正常运行。

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
final ClientConfig config = new DefaultClientConfig();
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(null, ctx));
Client create = Client.create(config);    
create.resource(targetUrl).post();

由于jersey-client.1.13不支持代理,因此我使用了jersey-apache-client.1.18 在下面的代码中,我使用了DefaultApacheHttpClientConfig ,添加了代理支持,并使用ApacheHttpClient创建了客户端。

SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
final DefaultApacheHttpClientConfig apacheConfig = new DefaultApacheHttpClientConfig();
final Map<String, Object> properties = apacheConfig.getProperties();
properties.put(DefaultApacheHttpClientConfig.PROPERTY_PROXY_URI, "http://" + proxyHost + ":" + proxyPort);
properties.put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(null,ctx));   
apacheConfig.getState().setProxyCredentials(AuthScope.ANY_REALM, proxyHost,   Integer.parseInt(proxyPort),proxyUser, proxyPassword);
Client create = ApacheHttpClient.create(apacheConfig);
create.resource(targetUrl).post();

我找不到解决方案。 在这两种情况下,证书都很好。

注意 :我也尝试了没有代理的jersey apache客户端,仍然存在错误。

有人发现哪里出了问题吗? 提前致谢。

原因是正在为Jersey配置SSL套接字工厂,但是您使用的是Jersey Apache连接器,因此应该直接在Apache HttpClient上配置SSL套接字工厂。 对于更高版本的Jersey(2.x),可以为您完成此操作,但是对于Apache连接器和Jersey 1.x,则需要进行配置。 像这样:

Protocol apacheProtocol = new Protocol("https", socketFactory, 443);
HostConfiguration hostConfig = new HostConfiguration();
hostConfig.setHost("your.hostname.org", 443, apacheProtocol);
HttpClient httpClient = new HttpClient();
httpClient.setHostConfiguration(hostConfig);
ApacheHttpClientHandler handler = new ApacheHttpClientHandler(httpClient);
Client client = new ApacheHttpClient(handler);

这里的另一个问题是,如果您在Jersey WebResource(设置主机名和端口)上使用绝对URI,则带有自定义SSLSocketFactory的HostConfiguration将被覆盖-HttpClient将默认使用JVM的CA证书(至少对Apache Client 3.1正确)。 。

如果以前对您有用,那么您可能一直在使用JVM cacerts信任的证书。 实际上,这里的一个选项是使用命令行密钥工具将您正在使用的证书手动添加到JVMs cacerts文件中(尽管对于某些应用程序,这可能不是可接受的解决方案)。

基本上,此问题是由于本地JAVA与https站点之间的密码不匹配所致。 您可能需要为JVM安装JCE扩展。

使用https://www.ssllabs.com/检查您的REST API是否支持Java, 请检查此图像示例

如果显示如下,则可以从http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html下载文件。 完成后,将JRE的lib / security目录下的两个JAR(local_policy.jar,US_export_policy.jar)替换为下载包中的两个JAR。

如果没有,请提供更多详细信息,以便我们进行详细检查。

在这里检查解决方案我很累如何调试ssl连接错误 ,它对我有用 ,并节省了我的时间!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM