【问题标题】:Has Android changed SSL configuration in API 24?Android 是否更改了 API 24 中的 SSL 配置?
【发布时间】:2016-12-10 17:47:30
【问题描述】:

当我的 Android 23 项目尝试通过 HTTPS 连接到我的服务器时,一切正常。

如果我将目标 SDK 切换到 24,我会收到以下错误:

 javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:361)
     at android.net.SSLCertificateSocketFactory.verifyHostname(SSLCertificateSocketFactory.java:198)
     at android.net.SSLCertificateSocketFactory.createSocket(SSLCertificateSocketFactory.java:443)
     at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:394)
     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:170)
     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:366)
     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
     at com.worklight.wlclient.WLRequestSender.run(WLRequestSender.java:47)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
     at java.lang.Thread.run(Thread.java:761)
 Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
     at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:563)
     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:444)
     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:508)
     at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:508)
     at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:401)
     at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:375)
     at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:304)
     at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
     at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
     at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:178)
     at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:596)
     at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
     at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
    ... 13 more
 Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

切换回 23,它又可以工作了。
24 年关于证书的最低要求有什么变化吗?

【问题讨论】:

    标签: android ssl


    【解决方案1】:

    如果您的targetSdkVersion 是 24+,则默认情况下不会在 Android 7.0 上合并用户通过设置应用安装的证书:

    默认情况下,来自所有应用的安全(例如 TLS、HTTPS)连接都信任预安装的系统 CA,而面向 API 级别 23 (Android M) 及以下的应用也默认信任用户添加的 CA 商店。

    (来自the network security configuration docs

    要解决这个问题,您需要定义一个network security configuration XML 资源:

    <?xml version="1.0" encoding="utf-8"?>
    
    <network-security-config>
        <base-config>
            <trust-anchors>
                <certificates src="system"/>
                <certificates src="user"/>
            </trust-anchors>
        </base-config>
    </network-security-config>
    

    然后,从清单中 &lt;application&gt; 元素中的 android:networkSecurityConfig 属性指向该 XML 资源。


    一般来说,Android 7.0 通过网络安全配置子系统(android.security.net.config.RootTrustManager 和堆栈跟踪中的 kin)路由 HTTPS。这里可能还引入了与targetSdkVersion 相关的其他兼容性问题。因此,如果缺少用户证书不是您的问题,您可以创建一个重现问题的示例项目file an issue。由于我维护a backport of that stuff,因此我有兴趣了解任何错误。 :-)

    【讨论】:

    • 是的,我在您发布此信息时发现了该信息。事实上,我的证书似乎在用户安装的信任中。
    • @NathanH:您的应用可以通过&lt;certificates src="user"/&gt; 选择使用用户安装的证书。但是,如果可能,请做其他事情。用户安装的证书是设备范围的,这不是很好。您应该能够设置一个network security configuration,将所需的证书烘焙到您的应用程序中。
    • 我应该把你提供的这个 XML 行放在哪里?我不太担心真正的安全性,这是为了测试
    • @NathanH:这将放在 XML 资源中,您可以在其中提供 network security configurationlike this 的东西,但是你包含 &lt;certificates src="user"/&gt; 并删除 &lt;certificates src="@raw/extracas"/&gt;(你不会有)应该可以工作。然后,将android:networkSecurityConfig 添加到&lt;application&gt;,指向该XML 资源。
    • 有效!您是否介意将此解决方法也添加到您的答案中?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    相关资源
    最近更新 更多