【问题标题】:Need help debugging SSLHandshakeException in Android Nougat需要帮助在 Android Nougat 中调试 SSLHandshakeException
【发布时间】:2017-02-16 13:57:30
【问题描述】:

我有一个从 3rd 方网站下载文档的应用程序(离线浏览)。

我使用的是标准的 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(使用站点证书构建)进行测试,并使用“信任所有”信任管理器进行测试。 需要注意的是,在使用时,永远不会使用“trust all”管理器。

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>

【问题讨论】:

  • 我猜您的目标是 API 24。针对 API 24 时,网络安全方面有一些变化。我认为简单的解决方法是针对 API 23。试一试,看看是否有帮助。
  • 您能否发布使用蹩脚密码执行与网站连接的代码?
  • 我在 Exchange 2007 服务器上遇到了完全相同的问题。你最后找到解决办法了吗?
  • 你好。你找到解决办法了吗?
  • @Andigor 不,走另一条路。

标签: android ssl sslhandshakeexception android-7.0-nougat


【解决方案1】:

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

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

该应用适用于其他服务器,但不适用于此特定服务器(与您的密码参数相同)。

旧版 Android(6 及更低版本)上的相同应用运行良好。 如果您为旧版本构建也没关系。它在 7 日崩溃。

SSL 堆栈发生了一些变化。

问候

【讨论】:

  • 是的,这太糟糕了...顺便说一句,Android HttpUrlConnection 是基于 Okhttp 的,所以这是正常的,它会给你同样的结果。
【解决方案2】:

使用适用于 Android 的 Net Cipher Library 来解决这个问题。

HttpUrlConnection connection = NetCipher.getHttpsURLConnection(url);

Gradle 依赖

compile 'info.guardianproject.netcipher:netcipher:1.2'

【讨论】:

    【解决方案3】:

    Android 更改了他们在早期版本中使用的名为 openssl 库的 ssl 库。但是在牛轧糖中,他们用自己的名为boringssl 的库替换了openssl。可能是因为您遇到了问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-22
      • 2013-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多