javax.net.ssl.SSLHandshakeException:向服务器发送请求时发生java.security.cert.CertPathValidatorException

时间:2014-12-12 06:25:39

标签: java android ssl https httpsurlconnection

我正在尝试使用以下代码连接到服务器并向其发送基于HTTPS的请求:

// create the URL with the target URL specified
URL url = new URL(vTargetURL);

// create a HTTP connection to the URL specified
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();

// set the timeout for the request
urlConnection.setReadTimeout(30000);

//add request header
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Length", String.valueOf(vRequestXML.length()));
for (HashMap.Entry<String, String> entry : vHttpHeaders.entrySet()) {           
    urlConnection.setRequestProperty(entry.getKey(), entry.getValue());
}


// send the request
DataOutputStream dataOutputStream = new DataOutputStream(urlConnection.getOutputStream());
dataOutputStream.writeBytes(vRequestXML);
dataOutputStream.flush();
dataOutputStream.close();

// read the response
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String inputLine;

StringBuffer response = new StringBuffer();         
while ((inputLine = bufferedReader.readLine()) != null) {
    response.append(inputLine);
}                   
bufferedReader.close();

我面临的问题是我的代码在声明中失败

DataOutputStream dataOutputStream = new DataOutputStream(urlConnection.getOutputStream());

带有例外

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

我只知道有一些与服务器证书有关的问题。我可以使用以下代码绕过此问题:

final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};  

urlConnection.setHostnameVerifier(DO_NOT_VERIFY);

// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {

    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return new java.security.cert.X509Certificate[] {};
    }

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

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

// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
catch (Exception e) {
    e.printStackTrace();
}

另外,当我在website上检查服务器地址时,出现以下错误

enter image description here

我知道相信所有主持人并不是解决这个问题的方法,但我无法总结如何解决这些问题。具体来说,我想了解:

  1. 出现此类例外的可能原因是什么。
  2. 如何解决问题。
  3. 任何线索都表示赞赏。

    感谢。

1 个答案:

答案 0 :(得分:0)

当您建立HTTPS连接时,您连接的服务器会发送证书以证明您拥有正确的服务器。此证书通常由另一个证书(由CA(证书颁发机构)的证书)签名,或者由另一个证书签署,该证书又签署。无论链条长多久,您都可以在底部找到CA的证书。

你怎么知道这个CA证书还可以? Java通过将所有可信CA的证书存储在密钥库(cacerts)中来解决此问题。

您遇到的错误很可能是由CA签署的证书的结果,而该证书不在密钥库中。它可以是自签名证书(证书本身作为自己的CA),由某公司的内部CA签署的证书,也可以是小型未知CA.

哟必须决定是否要信任此CA签署的所有证书。在这种情况下,请获取CA证书,并将其放在cacerts文件中。

我不知道如何在Android上做到这一点。执行此操作的标准java工具是keytool。