`
wenjinglian
  • 浏览: 822676 次
  • 性别: Icon_minigender_1
  • 来自: 株洲->深圳
社区版块
存档分类
最新评论

javax.net.ssl.SSLHandshakeException: sun.security.validator 问题解决,与环境有关

    博客分类:
  • JAVA
阅读更多

用httpclient访问https 资源时,会出现异常,与环境也有关系,有些机器请求正常.

 

 错误详情:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1623)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:198)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:192)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1074)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:128)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:529)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:465)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:884)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1120)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1147)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1131)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:166)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1049)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
        at com.msd.payCenter.msdPay.yeePay.util.HttpUtils.URLGet(HttpUtils.java:67)
        at com.msd.payCenter.msdPay.yeePay.service.impl.YeePayServiceImpl.yeeAutoCheckOrder(YeePayServiceImpl.java:298)
        at com.msd.payCenter.msdPay.AutoCheckOrderServiceImpl.autoCheckOrder(AutoCheckOrderServiceImpl.java:83)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

 

 

解决方法:

增加一个自己的https协议类 MySSLSocketFactory.java

 

 

package com.nassir.hc3;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

public class MySSLSocketFactory implements ProtocolSocketFactory {
    static {
        System.out.println(">>>>in MySSLSocketFactory>>");
    }
    private SSLContext sslcontext = null;

    private SSLContext createSSLContext() {
        SSLContext sslcontext = null;
        try {
            sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null,
                    new TrustManager[] { new TrustAnyTrustManager() },
                    new java.security.SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslcontext;
    }

    private SSLContext getSSLContext() {
        if (this.sslcontext == null) {
            this.sslcontext = createSSLContext();
        }
        return this.sslcontext;
    }

    public Socket createSocket(Socket socket, String host, int port,
            boolean autoClose) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(socket, host,
                port, autoClose);
    }

    public Socket createSocket(String host, int port) throws IOException,
            UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port);
    }

    public Socket createSocket(String host, int port, InetAddress clientHost,
            int clientPort) throws IOException, UnknownHostException {
        return getSSLContext().getSocketFactory().createSocket(host, port,
                clientHost, clientPort);
    }

    public Socket createSocket(String host, int port, InetAddress localAddress,
            int localPort, HttpConnectionParams params) throws IOException,
            UnknownHostException, ConnectTimeoutException {
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null");
        }
        int timeout = params.getConnectionTimeout();
        SocketFactory socketfactory = getSSLContext().getSocketFactory();
        if (timeout == 0) {
            return socketfactory.createSocket(host, port, localAddress,
                    localPort);
        } else {
            Socket socket = socketfactory.createSocket();
            SocketAddress localaddr = new InetSocketAddress(localAddress,
                    localPort);
            SocketAddress remoteaddr = new InetSocketAddress(host, port);
            socket.bind(localaddr);
            socket.connect(remoteaddr, timeout);
            return socket;
        }
    }

    private static class TrustAnyTrustManager implements X509TrustManager {

        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }
}

 

 

请求类:

 

 

/**
 * 
 */
package com.nassir.hc3;

import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.Protocol;

/**
 * @author nassir wen
 * @data 2012-3-31 下午05:09:13
 * @version V2.5
 * @Company: MSD.
 * @Copyright Copyright (c) 2012
 */
public class HttpsRequest {

    /**
     * 
     * @param url
     * @return
     */
    public static String post(String url) {
        //增加下面两行代码
        Protocol myhttps = new Protocol("https", new MySSLSocketFactory(), 443);
        Protocol.registerProtocol("https", myhttps);
        
        HttpClient client = new HttpClient();
        HttpMethod post = new PostMethod(url);
        try {
            client.executeMethod(post);
            byte[] responseBody = post.getResponseBody();
            String result = new String(responseBody,"GBK");
            return result;
        } catch (HttpException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            post.releaseConnection();
        }
        return null;
    }
}
 

 

 

测试:

 

public static void main(String[] args) {
        System.out.println(HttpsRequest.post("https://www.alipay.com"));//支付宝做测试
    }

 

 

解决方案来源:http://hi.baidu.com/69hwj/blog/item/3e9e457bf2f8b1f10bd18766.html

 

附件包含:以上代码以及httpclient3.x与httpclient4.x 事例.

 


 

 

 

 

  • 大小: 7 KB
分享到:
评论
1 楼 Trinea 2013-08-28  
可通过客户端信任所有证书或是服务器端添加证书两种方式解决,具体原因分析及解决方式见:http://www.trinea.cn/android/android-java-https-ssl-exception-2/

相关推荐

Global site tag (gtag.js) - Google Analytics