上班上的好好的,一個其他部門的同僚來着手機來說,APP在他的手機上登入不進去。
實在是最近沒有進行更新,在其他手機上也是好好的呀 ~~~
然後他說他以前也是好的,最近手機更新了一次。一檢視版本,Android6.0(小米4);
然後測試了一下三星6.0,Nexus6.0的結果都進不去,Android5.0,Android4.0的都
沒有問題,是以應該是Android6.0Google對其進行了一些修改。
debug後發現重寫的parseNetworkResponse()方法進不去。是以請求網絡傳回的資料無法解析。
然後跟蹤到源碼。發現NetworkDispatcher.java這個類裡面
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICN2kzMzIDMxEjNwQDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
進入到了VolleyError裡面。
報錯com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: Handshake failed
其實如果不是用的https用http的話就不會有這樣的問題。因為本身我們的代碼是對https的通路做過處理了的。
public class _FakeX509TrustManager implements X509TrustManager {
private static TrustManager[] trustManagers;
private static final X509Certificate[] _AcceptedIssuers = new X509Certificate[] {};
public boolean isClientTrusted(X509Certificate[] chain) {
return true;
}
public boolean isServerTrusted(X509Certificate[] chain) {
return true;
}
/**
* 允許所有SSL連接配接 調用此方法,可以解決Not trusted server certificate異常
*/
public static void allowAllSSL() {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String s, SSLSession sslsession) {
return true;
}
});
SSLContext context = null;
if (trustManagers == null) {
trustManagers = new TrustManager[] { new _FakeX509TrustManager() };
}
try {
context = SSLContext.getInstance("TLS");
context.init(null, trustManagers, new SecureRandom());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
HttpsURLConnection.setDefaultSSLSocketFactory(context
.getSocketFactory());
}
public void checkClientTrusted(X509Certificate[] ax509certificate, String s)
throws java.security.cert.CertificateException {
}
public void checkServerTrusted(X509Certificate[] ax509certificate, String s)
throws java.security.cert.CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return _AcceptedIssuers;
}
}
是以在想不應該出現這個問題啊。。
那麼在Android6.0以下的版本和非https的通路路徑不會有問題的話。
這樣是不是可以總結為Android6.0對https的通路做了修改呢???
檢視資料發現:
Google 現在用BoringSSL 代替了OpenSSL ,而且開始應用到一些Google産品,AndroidM就
開始采用的BoringSSL。是以就找到問題的所在了~~
Tomcat伺服器側的SSL/TLS配置存在安全漏洞導緻Android6.0上的BoringSSL報錯!!!
SSL/TLS握手過程中,假如選中了諸如TLS_DHE_RSA_WITH_AES_128_CBC_SHA這樣使用deffie-hellman密鑰的cipher,那麼在deffie-hellman密鑰交換過程中會使用的一個P參數(prime number),伺服器側提供的P參數在JDK8之前都隻用了768bit的長度,小于1024bit存在安全漏洞可導緻logjam attack,會被最新本版的浏覽器和BoringSSL拒絕。
最後最後的解決方式是:
讓背景在伺服器的Tomcat 的server.xml的connector配置裡顯示聲明使用哪些cipher來排除用到deffie-hellman密鑰的,加上一下配置 :
<Connector port="443" SSLEnabled="true" sslProtocol="TLS"
ciphers="TLS_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_256_CBC_SHA,
SSL_RSA_WITH_3DES_EDE_CBC_SHA"
…… />
最後問題就解決了。。。
看别人說将Tomact的JDK更新到8也闊以,,,這個就沒有試了。
對了,Android6.0删除了HttpClient的相關類~~
android 6.0(api 23) SDK,不再提供org.apache.http.*(隻保留幾個類).
可以在libs中加入
org.apache.http.legacy.jar
或者直接在相應的module下的build.gradle中加入:
android {
useLibrary ‘org.apache.http.legacy’
}
注意放置的位置:是在android {}中