对等点未在 Java 中进行身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28196074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Peer not authenticated in java
提问by Amogh
I have gone to almost all the post related to this exception. Actually my problem is I have an java application through which I am hitting an URL and getting response from it.
我已经阅读了几乎所有与此异常相关的帖子。实际上我的问题是我有一个 java 应用程序,通过它我点击了一个 URL 并从中获得响应。
code to hit URL is :
命中 URL 的代码是:
HttpGet getRequest = new HttpGet("https://urlto.esb.com");
HttpResponse httpResponse = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
httpResponse = httpClient.execute(getRequest);
Here I am getting javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
我在这里得到 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
So after some Google search I come to know that I can import certificate in keystore of java where the application is running. so I imported certificate in keystore and this code is working. but i don't want this solution so after some more searching I come to know that I can use TrustManager
for the same thing without importing certificate into keystore. So I have written code like:
因此,经过一些 Google 搜索后,我知道我可以在运行应用程序的 Java 密钥库中导入证书。所以我在密钥库中导入了证书并且此代码正在运行。但我不想要这个解决方案,所以经过更多搜索后,我知道我可以TrustManager
在不将证书导入密钥库的情况下用于相同的事情。所以我写了这样的代码:
@Test
public void withTrustManeger() throws Exception {
DefaultHttpClient httpclient = buildhttpClient();
HttpGet httpGet = new HttpGet("https://urlto.esb.com");
HttpResponse response = httpclient.execute( httpGet );
HttpEntity httpEntity = response.getEntity();
InputStream inputStream = httpEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
inputStream.close();
String jsonText = sb.toString();
System.out.println(jsonText);
}
private DefaultHttpClient buildhttpClient() throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, getTrustingManager(), new java.security.SecureRandom());
SSLSocketFactory socketFactory = new SSLSocketFactory(sc);
Scheme sch = new Scheme("https", 443, socketFactory);
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
return httpclient;
}
private TrustManager[] getTrustingManager() {
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
// Do nothing
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
// Do nothing
}
} };
return trustAllCerts;
}
This code is also working but My question is I am not checking anything related to certificates then how connection is trusted. after debugging I come to know that only checkServerTrusted
is hitting. So I have write something in checkServerTrusted
to validate certificates that come in certs
and the one which is in my application like some .cer or .crt file.
此代码也有效,但我的问题是我没有检查与证书相关的任何内容,以及如何信任连接。调试后我才知道只有checkServerTrusted
命中。所以我写了一些东西checkServerTrusted
来验证进来的证书certs
和我的应用程序中的证书,比如一些 .cer 或 .crt 文件。
Every Help will be appreciated.
每一个帮助将不胜感激。
Update after @EpicPandaForce (Using Apache HttpClient 4.3)
在@EpicPandaForce 之后更新(使用 Apache HttpClient 4.3)
try
{
keyStore = KeyStore.getInstance("JKS");
InputStream inputStream = new FileInputStream("E:\Desktop\esbcert\keystore.jks");
keyStore.load(inputStream, "key".toCharArray());
SSLContextBuilder sslContextBuilder = SSLContexts.custom().loadTrustMaterial(keyStore, new TrustSelfSignedStrategy());
sslcontext = sslContextBuilder.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
HttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
HttpGet httpGet = new HttpGet("https://url.esb.com");
HttpResponse response = httpclient.execute( httpGet );
HttpEntity httpEntity = response.getEntity();
InputStream httpStram = httpEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpStram));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
httpStram.close();
inputStream.close();
String jsonText = sb.toString();
System.out.println(jsonText);
}
catch(Exception e)
{
System.out.println("Loading keystore failed.");
e.printStackTrace();
}
采纳答案by EpicPandaForce
Technically, seeing as you are using Apache HttpClient 4.x, a simpler solution would be the following:
从技术上讲,当您使用 Apache HttpClient 4.x 时,更简单的解决方案如下:
SSLContext sslcontext = null;
try {
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());
sslcontext = sslContextBuilder.build();
Where trustStore
is initialized like this
哪里trustStore
是这样初始化的
KeyStore keyStore = null;
try {
keyStore = KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME); //you can use JKS if that is what you have
InputStream inputStream = new File("pathtoyourkeystore");
try {
keyStore.load(inputStream, "password".toCharArray());
} finally {
inputStream.close();
}
} catch(Exception e) {
System.out.println("Loading keystore failed.");
e.printStackTrace();
}
return keyStore;
}
And then create the HttpClient
然后创建HttpClient
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
httpclient = HttpClients
.custom()
.setSSLSocketFactory(sslsf).build();
EDIT: Exact code for me was this:
编辑:对我来说确切的代码是这样的:
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());
sslcontext = sslContextBuilder.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, new String[] {"TLSv1"}, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
);
httpclient = HttpClients
.custom()
.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
.setSSLSocketFactory(sslsf).build();