我有一个应用程序可以从第 3 方网站下载文档(以便离线浏览)。
我正在使用标准的 HttpUrlConnection。
它曾经像魅力一样工作,但自从升级到牛轧糖后,其中一个网站产生了非常一致的 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 上的相同内容已更新为牛轧糖。 我的应用程序工作正常,现在不再工作了。
我尝试使用替代库 (OkHttp),但结果相同。 javax.net.ssl.SSLHandshakeException: 连接被对端关闭
该应用程序适用于其他服务器,但不适用于此特定服务器(与您的密码参数相同)。
同一应用在旧版 Android(6 及以下)上运行良好。 如果您为旧版本构建并不重要。它在 7 日崩溃。
SSL 堆栈发生了一些变化。
问候
关于android - 需要帮助在 Android Nougat 中调试 SSLHandshakeException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39919420/