[英]Peer not authenticated in java
我去了幾乎所有與此例外相關的帖子。 實際上,我的問題是我有一個Java應用程序,通過該應用程序可以訪問URL並從中獲取響應。
到達網址的代碼是:
HttpGet getRequest = new HttpGet("https://urlto.esb.com");
HttpResponse httpResponse = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
httpResponse = httpClient.execute(getRequest);
在這里,我得到javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
因此,經過一些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;
}
該代碼也可以正常工作,但是我的問題是我沒有檢查與證書相關的任何內容,而是如何信任連接。 調試后,我知道只有checkServerTrusted
在運行。 因此,我在checkServerTrusted
編寫了一些內容,以驗證證書中附帶的certs
以及應用程序中的.cer或.crt文件中的certs
。
每個幫助將不勝感激。
@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();
}
從技術上講,看到您正在使用Apache HttpClient 4.x時,以下是一個更簡單的解決方案:
SSLContext sslcontext = null;
try {
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());
sslcontext = sslContextBuilder.build();
像這樣初始化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;
}
然后創建HttpClient
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext);
httpclient = HttpClients
.custom()
.setSSLSocketFactory(sslsf).build();
編輯:對我來說確切的代碼是這樣的:
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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.