【问题标题】:android https CertPathValidatorException: TrustAnchor found but certificate validation failedandroid https CertPathValidatorException:找到TrustAnchor,但证书验证失败
【发布时间】:2016-11-21 04:41:12
【问题描述】:

是否有人遇到以下异常。

它随机发生。发生这种情况后,就不能再使用 https 连接了。整个应用程序需要重新启动。

场景: 详细跟踪代码后,我更新了场景:

1. The application has 3 process in the same application.
2. The main ui process invoke https request in another thread.
3. The another 2 processes hold the 2 servcies. one service will also invoke https request in another thread.
4. When user logout, it will stop the 2 services.
3. When user login again, the main ui process invoke https request and then fail.

代码如下:

URL url = new URL(mUri);
urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestMethod(mMethod);
if (mMethod.equals(HttpPost.METHOD_NAME)) {
    urlConnection.setDoOutput(true);
}
else {
    urlConnection.setDoOutput(false);
}
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
urlConnection.setChunkedStreamingMode(0);
...
if (!TextUtils.isEmpty(mJsonContent)) {
    OutputStreamWriter wr = new OutputStreamWriter(urlConnection.getOutputStream());
    wr.write(mJsonContent);
    wr.close();
}
//Get Response
InputStream inputStream;
int statusCode;
statusCode = urlConnection.getResponseCode();
...
inputStream = urlConnection.getInputStream();
String bodyContent = convertStreamToString(inputStream);
inputStream.close();

if (urlConnection != null) {
    urlConnection.disconnect();
}

我想知道根本原因是什么。目前我不知道如何解决这个错误。 https 连接在另一个线程中运行。得到响应后,它会回发到主线程。

W/System.err( 7158): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.

W/System.err( 7158):    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:409)

W/System.err( 7158):    at com.android.okhttp.Connection.upgradeToTls(Connection.java:146)

W/System.err( 7158):    at com.android.okhttp.Connection.connect(Connection.java:107)

W/System.err( 7158):    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)

W/System.err( 7158):    at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)

W/System.err( 7158):    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)

W/System.err( 7158):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)

W/System.err( 7158):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89)

W/System.err( 7158):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:197)

W/System.err( 7158):    at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:254)

W/System.err( 7158):    at com.xxxx.xxx.util.http.AsyncHttpsClient$AsyncRequest.run(AsyncHttpsClient.java:304)

W/System.err( 7158):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)

W/System.err( 7158):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)

W/System.err( 7158):    at java.lang.Thread.run(Thread.java:841)

W/System.err( 7158): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.

W/System.err( 7158):    at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:308)

W/System.err( 7158):    at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:202)

W/System.err( 7158):    at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:611)

W/System.err( 7158):    at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)

W/System.err( 7158):    at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:405)

W/System.err( 7158):    ... 13 more

W/System.err( 7158): Caused by: java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.

W/System.err( 7158):    at com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:122)

W/System.err( 7158):    at java.security.cert.CertPathValidator.validate(CertPathValidator.java:190)

W/System.err( 7158):    at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:295)

W/System.err( 7158):    ... 17 more

W/System.err( 7158): Caused by: com.android.org.bouncycastle.jce.provider.AnnotatedException: TrustAnchor found but certificate validation failed.

W/System.err( 7158):    at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.findTrustAnchor(CertPathValidatorUtilities.java:235)

W/System.err( 7158):    at com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:117)

W/System.err( 7158):    ... 19 more

W/System.err( 7158): Caused by: java.security.NoSuchAlgorithmException: error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm

W/System.err( 7158):    at com.android.org.conscrypt.NativeCrypto.X509_verify(Native Method)

W/System.err( 7158):    at com.android.org.conscrypt.OpenSSLX509Certificate.verifyOpenSSL(OpenSSLX509Certificate.java:334)

W/System.err( 7158):    at com.android.org.conscrypt.OpenSSLX509Certificate.verify(OpenSSLX509Certificate.java:367)

W/System.err( 7158):    at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.verifyX509Certificate(CertPathValidatorUtilities.java:1427)

W/System.err( 7158):    at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.findTrustAnchor(CertPathValidatorUtilities.java:222)

W/System.err( 7158):    ... 20 more

【问题讨论】:

  • 是在所有设备上发生还是仅在特定设备或 Android 版本上发生?
  • 目前在 Nexus 5 4.4.4 上更容易发生。

标签: android https okhttp


【解决方案1】:

根据 [1,2] 等其他来源,您可能已经过时的 OpenSSL 版本。尝试更新您的 openSSL 版本。最低版本:OpenSSL 0.9.8o

您的 BouncyCastle 使用 OpenSSL com.android.org.conscrypt.OpenSSLX509Certificate.verify 来验证证书。

java.security.NoSuchAlgorithmException: error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm 异常表示证书使用 OpenSSL 中未处理的摘要,很可能是 SHA256。

更新 01: 如 cmets 中所述,在 Android 中,您无法更新系统 OpenSSL。 让我们进行实验:

您的 Android 和 OKHttp 版本是什么?您的系统使用https://conscrypt.org/ 作为加密提供者。您可以尝试通过使用新版本的 BouncyCastle - SpongyCastle 来避免使用系统捆绑的 OpenSSL 和 BouncyCastle 版本。

按照https://rtyley.github.io/spongycastle/ 此处的说明将 SpongyCastle 安装为新的首选加密提供程序(coreprovpkix)。如果 SpongyCastle 生效,您的堆栈跟踪将包含 spongycastle 包。

【讨论】:

  • 通常OpenSSL是Android OS的一部分,不能单独更新。
  • 我使用的是android okhttp,我认为无法更新设备的openssl。唯一的方法是我不使用 okhttp?但它并不是 100% 发生在设备中。一开始没问题。它有时会在注销后发生,然后再次登录。我想知道导致这个问题发生的方式是什么?是服务器和客户端握手的问题,服务器选择不同的摘要导致问题吗?有时服务器选择在客户端支持的摘要,有时在客户端选择不支持握手?
  • 我的设备是 android 4.4.4 和 android 5.0.2。我使用设备谷歌浏览器查看MyClient.html。它支持 SHA256,如下所示。我还测试了服务器。我将其发布在另一个答案中,因为有很多要提的。非常感谢您的观看。
  • 这很奇怪。海绵城堡呢?你试过了吗?
  • 你看到我的另一篇回答了吗?您如何看待这 2 条认证途径?海绵城堡我没试过。
猜你喜欢
  • 1970-01-01
  • 2023-03-31
  • 2014-09-24
  • 2020-11-01
  • 2019-04-20
  • 2012-03-15
  • 2011-09-17
  • 1970-01-01
  • 2015-02-01
相关资源
最近更新 更多