![](/img/trans.png)
[英]Apache HttpClient Error: javax.net.ssl.SSLPeerUnverifiedException: Peer Not Authenticated
[英]javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated only on production server
我們的服務器突然無法再通過httpclient
將請求發布到另一個第三服務,並且目前沒有人可以登錄到系統。 這是我們的后端代碼
public byte[] postContent(final String url, Object... data) {
Map<String, String> keyValuePairs = SystemUtils.getInstance().buildMap(new HashMap<String, String>(), data);
final long startTiming = System.currentTimeMillis();
logger.info("posting, url: " + url);
HttpClient httpClient = getHttpClient();
try {
HttpPost httpPost = new HttpPost(url);
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
for (String key : keyValuePairs.keySet()) nvps.add(new BasicNameValuePair(key, keyValuePairs.get(key)));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
ResponseHandler<byte[]> responseHandler = new ResponseHandler<byte[]>() {
public byte[] handleResponse(final HttpResponse response) throws IOException {
int status = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
logger.info("done posting, process: " + (System.currentTimeMillis() - startTiming) + "ms, url: " + url);
return entity != null ? EntityUtils.toByteArray(entity) : null;
}
};
return httpClient.execute(httpPost, responseHandler); // cannot execute
}
catch (Exception e) {
throw new SystemException(url + ", " + keyValuePairs.toString(), e);
}
}
private HttpClient getHttpClient() {
HttpClient base = new DefaultHttpClient(cm);
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = base.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
HttpClient client = new DefaultHttpClient(ccm, base.getParams());
return client;
} catch(Exception ex) {
ex.printStackTrace();
return base;
}
}
這是例外
co.abc.xyz.infra.exception.SystemException: https://api.com/verify/json, {....}
at co.abc.xyz.infra.helper.HttpHelper.postContent(HttpHelper.java:155)
at co.abc.xyz.infra.helper.NexmoHelper.sendChallenge(NexmoHelper.java:70)
at co.abc.xyz.infra.controller.SecurityController.mrequestPost(SecurityController.java:89)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at
....
Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:421)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:126)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:437)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:151)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:125)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:643)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1138)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1076)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1050)
at co.abc.xyz.infra.helper.HttpHelper.postContent(HttpHelper.java:152)
... 75 more
在我本地,一切正常,這僅在生產服務器上發生。 有沒有人對此有任何線索?
您沒有任何證書和信任庫? 也許是因為缺少信任庫...我建議您檢查每個系統環境上的根證書和證書鏈是否相同(和有效)。
如果您使用的是Spring / Apache HTTP Client,則還可以像這樣初始化SSLContext(取決於Keystore / Trustore類型):
final KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(keyStoreFile.getInputStream(), keyStorePassword.toCharArray());
final KeyStore trustStore = KeyStore.getInstance("JCEKS");
trustStore.load(trustStoreFile.getInputStream(), trustStorePassword.toCharArray());
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(
trustStore,
new TrustStrategy(){
@Override
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
})
.loadKeyMaterial(
keyStore,
keyStorePassword.toCharArray())
.build();
另外,您可以添加-Djavax.net.debug=ssl
以在JVM上打開SSL調試。
我將電子郵件發送給第三服務詢問該問題,並得到他們剛剛更新為TLSv1.2的答復,因此,默認情況下,Java 1.7使用TLSv1.1並給出了此異常。
我只需要換線
SSLContext ctx = SSLContext.getInstance("TLS");
至
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
服務器又恢復正常。 這真是悲劇。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.