繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM