我有一个应用程序可以从第三方网站下载文档(以离线浏览)。

我正在使用标准的HttpUrlConnection。

它曾经像魅力一样运作,但是自从升级到Nougat以来,其中一个站点产生了非常一致的SSLHandshakeException,其他站点运行良好。

我尝试使用新的应用程序证书,没有运气。
我什至尝试了“信任所有证书” TrustManager的旧技巧。没运气。 TrustManager ID甚至不查询。

我注意到尽管该服务器使用的是相当旧的密码。

...
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol  : TLSv1
Cipher    : RC4-MD5
...


难道是我遇到麻烦的原因吗?如果是,该如何将该密码添加到我的连接中?

谢谢

编辑1:该应用程序以SDK 22为目标,并且也针对API 22进行编译

编辑2:
该代码已被破解,可以使用“强制” CA(使用站点的证书进行构建)进行测试,还可以使用“全部信任”信任管理器进行测试。
要注意的是,在使用中,从未使用“全部信任”管理器。

SSLContext sslContext = null;

if (testWitCa) {

    Certificate ca = null;
    try {
        ca = cf.generateCertificate(caInput);
        Log.v(this, "ca = " + ((X509Certificate) ca).getSubjectDN());
    } finally {
        caInput.close();
    }

    // Create a KeyStore containing our trusted CAs
    String keyStoreType = KeyStore.getDefaultType();
    KeyStore keyStore = KeyStore.getInstance(keyStoreType);
    keyStore.load(null, null);
    keyStore.setCertificateEntry("ca", ca);

    // Create a TrustManager that trusts the CAs in our KeyStore
    String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
    tmf.init(keyStore);

    // Create an SSLContext that uses our TrustManager
    sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, tmf.getTrustManagers(), null);

} else {

    final TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    Log.v(FileDownloader.this, "Checking client with %s", authType);
                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
                    Log.v(FileDownloader.this, "Checking server with %s", authType);
                }

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

    sslContext = SSLContext.getInstance("TLS");
    sslContext.init(null, trustAllCerts, null);
}

URL url = new URL(fromUrl);
HttpURLConnection httpConn;

httpConn = (HttpsURLConnection) url.openConnection();

if (sslContext != null) {
    ((HttpsURLConnection) httpConn).setSSLSocketFactory(sslContext.getSocketFactory());
}

responseCode = httpConn.getResponseCode();


我也尝试过使用以下安全配置文件(网站Thawte G3的根CA):

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

最佳答案

Nexus 6上的相同内容已更新为Nougat。
我的应用程序正常工作,现在不再工作。

我尝试使用替代库(OkHttp),但最终结果相同。
javax.net.ssl.SSLHandshakeException:连接被同级关闭

该应用程序可与其他服务器一起使用,但不能与特定服务器(与您的密码参数相同)一起使用。

在旧版Android(6及更低版本)上使用相同的应用程序效果很好。
如果您为较旧的版本进行构建,则没有关系。它在7崩溃。

SSL堆栈发生了某些变化。

问候

07-24 09:30