javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:未find证书path的信任锚

我正在使用Retrofit来访问我的REST API。 但是,当我把我的API后面的ssl和访问它通过http://myhost/myapi然后我得到这个错误:

我现在需要做额外的事情,我的API在SSL后面吗?

这是我如何连接:

 private final String API = "https://myhost/myapi"; private final RestAdapter REST_ADAPTER = new RestAdapter.Builder() .setServer(API) .setLogLevel(RestAdapter.LogLevel.FULL) .build(); 01-10 09:49:55.621 2076-2100/com.myapp.mobile D/Retrofit﹕ javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:401) at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209) at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478) at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433) at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290) at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240) at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282) at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497) at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134) at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:90) at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:48) at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:287) at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:222) at $Proxy12.signin(Native Method) at com.myapp.loginactivity$3.doInBackground(LoginActivity.java:143) at com.myapp.loginactivity$3.doInBackground(LoginActivity.java:136) at android.os.AsyncTask$2.call(AsyncTask.java:287) at java.util.concurrent.FutureTask.run(FutureTask.java:234) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) at java.lang.Thread.run(Thread.java:841) Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:282) at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:202) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:595) at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:398)            at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)            at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)            at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)            at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)            at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)            at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)            at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)            at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)            at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:90)            at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:48)            at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:287)            at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:222)            at $Proxy12.signin(Native Method)            at com.myapp.LoginActivity$3.doInBackground(LoginActivity.java:143)            at com.myapp.LoginActivity$3.doInBackground(LoginActivity.java:136)            at android.os.AsyncTask$2.call(AsyncTask.java:287)            at java.util.concurrent.FutureTask.run(FutureTask.java:234)            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)            at java.lang.Thread.run(Thread.java:841) 

Solutions Collecting From Web of "javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:未find证书path的信任锚"

发生这种情况的原因是JVM / Dalvik对系统中或用户证书存储中的CA证书没有信心。

为了解决这个与改进,如果你使用okhttp,与另一个客户端是非常相似的。
你必须这样做:

一个)。 创build一个包含CA公钥的证书存储区。 要做到这一点,你需要启动* nix的下一个脚本。 您需要在您的机器上安装openssl,并从https://www.bouncycastle.org/下载jar bcprov-jdk16-1.46.jar。 下载这个版本不是其他,版本1.5X是不兼容的Android 4.0.4。

 #!/bin/bash if [ -z $1 ]; then echo "Usage: cert2Android<CA cert PEM file>" exit 1 fi CACERT=$1 BCJAR=bcprov-jdk16-1.46.jar TRUSTSTORE=mytruststore.bks ALIAS=`openssl x509 -inform PEM -subject_hash -noout -in $CACERT` if [ -f $TRUSTSTORE ]; then rm $TRUSTSTORE || exit 1 fi echo "Adding certificate to $TRUSTSTORE..." keytool -import -v -trustcacerts -alias $ALIAS \ -file $CACERT \ -keystore $TRUSTSTORE -storetype BKS \ -providerclass org.bouncycastle.jce.provider.BouncyCastleProvider \ -providerpath $BCJAR \ -storepass secret echo "" echo "Added '$CACERT' with alias '$ALIAS' to $TRUSTSTORE..." 

B)。 将文件truststore mytruststore.bks复制到项目的res / raw中 信任库位置

C)。 设置连接的SSLContext:

 ............. okHttpClient = new OkHttpClient(); try { KeyStore ksTrust = KeyStore.getInstance("BKS"); InputStream instream = context.getResources().openRawResource(R.raw.mytruststore); ksTrust.load(instream, "secret".toCharArray()); // TrustManager decides which certificate authorities to use. TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ksTrust); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); okHttpClient.setSslSocketFactory(sslContext.getSocketFactory()); } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException e) { e.printStackTrace(); } ................. 

我知道有4种方法:

  • 将证书导入您的应用程序并将其用于连接
  • 禁用证书检查
  • 将您的证书添加到Android中的可信系统证书
  • 购买Android认可的validation证书

我假设你不想为此付出代价,所以我认为最优雅的解决scheme是第一个,可以这样完成的:

http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

嗨同样的问题,我已经解决了你可以试试这个

java.security.cert.CertPathValidatorException:未find证书path的信任锚点

  // SET SSL public static OkClient setSSLFactoryForClient(OkHttpClient client) { try { // Create a trust manager that does not validate certificate chains final TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { } @Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } } }; // Install the all-trusting trust manager final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // Create an ssl socket factory with our all-trusting manager final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); client.setSslSocketFactory(sslSocketFactory); client.setHostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); } catch (Exception e) { throw new RuntimeException(e); } return new OkClient(client); } 

SSLconfiguration不正确。 那些信任的错误通常意味着信任存储找不到。 检查你的configuration,确保你确实指向了信任存储,并且它已经到位。

确保你有一个-Djavax.net.ssl.trustStore系统属性集,然后检查path实际上是否导致信任存储。

您也可以通过设置此系统属性-Djavax.net.debug=all来启用SSLdebugging。 在debugging输出中,您会注意到它指出找不到信任存储。

这可能有几个原因,包括:

  1. 颁发服务器证书的CA是未知的
  2. 服务器证书不是由CA签名的,而是自签名的
  3. 服务器configuration缺less中间CA.

请查看这个链接的解决scheme: https : //developer.android.com/training/articles/security-ssl.html#CommonProblems