簡體   English   中英

javax.net.ssl.SSLHandshakeException:向服務器發送請求時,java.security.cert.CertPathValidatorException

[英]javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException while sending a request to the server

我正在嘗試連接到服務器,並使用以下代碼向其發送基於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();
}

另外,當我在此網站上檢查服務器地址時,出現以下錯誤

在此處輸入圖片說明

我知道信任所有主機並不能解決此問題,但是我無法得出結論如何解決這些問題。 具體來說,我想了解:

  1. 發生這種異常的可能原因是什么?
  2. 我該如何解決這些問題。

任何線索表示贊賞。

謝謝。

建立HTTPS連接時,連接的服務器會發送其證書以證明您擁有正確的服務器。 通常,此證書由另一個證書(由CA(證書頒發機構)的證書)簽名,或僅由另一個證書(后者又簽名)簽名。 無論該鏈有多長,在底部都可以找到CA的證書。

您如何知道此CA證書可以? Java通過將所有受信任CA的證書存儲在密鑰庫(證書)中來解決此問題。

您面臨的錯誤很可能是由不在密鑰庫中的CA簽署的證書導致的。 它可以是自簽名證書(證書本身充當自己的CA),由某個公司的內部CA簽名或由小型未知CA簽名的證書。

您必須決定是否要信任此CA簽名的所有證書。 在這種情況下,請獲取CA證書,並將其放入您的cacerts文件中。

我不知道如何在android上做到這一點。 執行此操作的標准Java工具是keytool。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM