简体   繁体   English

javax.net.ssl.SSLPeerUnverifiedException:仅在生产服务器上未对等身份验证

[英]javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated only on production server

Our server suddenly cannot post request to another 3rd service any more through the httpclient and currently there is no one can login to the system. 我们的服务器突然无法再通过httpclient将请求发布到另一个第三服务,并且目前没有人可以登录到系统。 This is our backend code 这是我们的后端代码

    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;
        }
    }

And this is the exception 这是例外

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

On my local, everything is working fine and this only happens on the production server. 在我本地,一切正常,这仅在生产服务器上发生。 Is there anyone having any clue for this? 有没有人对此有任何线索?

You do not have any certificate and truststore ? 您没有任何证书和信任库? Maybe it is because of the absence of truststore... I suggest you to check if root certificates and certificate chains are the same (and valids) on every system environments. 也许是因为缺少信任库...我建议您检查每个系统环境上的根证书和证书链是否相同(和有效)。

If you are using Spring/Apache HTTP Client, you can also init your SSLContext like this (depends on Keystore/Trustore types) : 如果您使用的是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();

Also, you can add -Djavax.net.debug=ssl to turn on SSL debugging on the JVM. 另外,您可以添加-Djavax.net.debug=ssl以在JVM上打开SSL调试。

I sent the email to the 3rd service to ask about the problem and got the reply that they just updated to TLSv1.2, thus by default Java 1.7 use TLSv1.1 and it gave this exception. 我将电子邮件发送给第三服务询问该问题,并得到他们刚刚更新为TLSv1.2的答复,因此,默认情况下,Java 1.7使用TLSv1.1并给出了此异常。

I only need to change the line 我只需要换线

SSLContext ctx = SSLContext.getInstance("TLS");

to

SSLContext ctx = SSLContext.getInstance("TLSv1.2");

And server is back to normal again. 服务器又恢复正常。 This is such a tragedy. 这真是悲剧。

暂无
暂无

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

相关问题 Apache HttpClient错误:javax.net.ssl.SSLPeerUnverifiedException:对等方未通过身份验证 - Apache HttpClient Error: javax.net.ssl.SSLPeerUnverifiedException: Peer Not Authenticated Java 8 javax.net.ssl.SSLPeerUnverifiedException:peer未经过身份验证,但不是Java 7 - Java 8 javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated, but not Java 7 javax.net.ssl.SSLPeerUnverifiedException:未在Tomcat中使用Apache HttpClient对等体进行身份验证 - javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated in Tomcat with Apache HttpClient javax.net.ssl.SSLPeerUnverifiedException:在netbeans中未对等身份验证 - javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated in netbeans JDK 11. javax.net.ssl.SSLPeerUnverifiedException:对等方未通过身份验证 - JDK 11. javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated Java - javax.net.ssl.SSLPeerUnverifiedException:peer未经过身份验证 - Java - javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 异常:javax.net.ssl.SSLPeerUnverifiedException:对等端未经过身份验证 - Exception : javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 如何使用Java解决Rally Rest api中的javax.net.ssl.SSLPeerUnverifiedException:对等体未通过身份验证的异常? - How to solve javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated Exception in Rally Rest api using java? javax.net.ssl.SSLPeerUnverifiedException:对等方未在jdk7中进行身份验证,但未在jdk8中进行身份验证 - javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated in jdk7 but not in jdk8 javax.net.ssl.SSLPeerUnverifiedException: 升级 Spring 从 2.1.0 到 2.2.0.M3 后未通过身份验证 - javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated after upgrading Spring Boot from 2.1.0 to 2.2.0.M3
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM