我有一个应用程序可以从第三方网站下载文档(以离线浏览)。
我正在使用标准的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堆栈发生了某些变化。
问候