gpt4 book ai didi

java - 将 Apache HttpComponents 用于 https 请求 : "peer not authenticated" and "handshake_failure" errors

转载 作者:太空宇宙 更新时间:2023-11-03 13:41:45 24 4
gpt4 key购买 nike

我正在尝试使用 Apache HttpComponents 库对 JBoss 服务器进行 HTTP GET 调用。当我使用 http URL 执行此操作时,它工作得很好,但是当我使用 https URL 时,它不起作用。这是我的代码:

public static String HttpGET(String requestURL, Cookie cookie)
throws HttpException {

DefaultHttpClient httpClient = new DefaultHttpClient();

if (cookie != null) {
CookieStore store = new BasicCookieStore();
store.addCookie(cookie);
((AbstractHttpClient) httpClient).setCookieStore(store);
}

HttpGet httpGet = new HttpGet(requestURL);

HttpResponse response = null;
HttpEntity responseEntity = null;
String responseBody = null;
try {
response = httpClient.execute(httpGet);
// Do some more stuff...

} catch (SSLPeerUnverifiedException ex) {
// Message "peer not authenticated" means the server presented
// a certificate that was not found in the local truststore.
throw new HttpException("HTTP GET request failed; possible"
+ " missing or invalid certificate: " + ex.getMessage());
} catch (IOException e) {
e.printStackTrace();
} finally {
// When HttpClient instance is no longer needed,
// shut down the connection manager to ensure
// immediate deallocation of all system resources
httpClient.getConnectionManager().shutdown();
}

return responseBody;
}

当我 execute() 我的 GET 调用时,我得到一个 SSLPeerUnverifiedException。错误信息是:

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

在大量谷歌搜索和 StackOverflow 问题搜索之后,我一直看到这个建议,所以我在我的 DefaultHttpClient 周围添加了这个包装器,如下所示:

private static HttpClient wrapClient(HttpClient httpClient) {       
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {

public void checkClientTrusted(X509Certificate[] xcs,
String string) {
}

public void checkServerTrusted(X509Certificate[] xcs,
String string) {
}

public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
X509HostnameVerifier verifier = new X509HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return false;
}

@Override
public void verify(String arg0, SSLSocket arg1)
throws IOException { }

@Override
public void verify(String arg0, X509Certificate arg1)
throws SSLException { }

@Override
public void verify(String arg0, String[] arg1, String[] arg2)
throws SSLException { }

};

ctx.init(null, new TrustManager[] { tm }, null);

SSLSocketFactory socketFactory = new SSLSocketFactory(ctx);
socketFactory.setHostnameVerifier(verifier);
Scheme sch = new Scheme("https", 443, socketFactory);
httpClient.getConnectionManager().getSchemeRegistry().register(sch);
return httpClient;

} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}

然而,这只会产生不同的错误:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure

我相信证书设置正确,因为使用 Jersey 库编写的其他代码可以成功连接到此服务器。但是,我没有看到我在使用 Apache HttpComponents 时做错了什么。有任何想法吗?如果我犯了明显的错误,我深表歉意,我是 SSL 的新手,还没有完全理解我在做什么。感谢您的帮助!

最佳答案

这可能是因为您的服务器需要服务器名称指示。

由于 Apache HTTP Client 4.2.2 似乎不支持 SNI(它不发送 server_name 扩展,即使在使用 Java 7 时),您可能会获得与之前不同的证书你会得到其他使用 SNI 的库。

似乎有办法得到SNI support with Apache HTTP Client 4.3 (但您至少仍需要 Java 7)。

关于java - 将 Apache HttpComponents 用于 https 请求 : "peer not authenticated" and "handshake_failure" errors,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18857138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com