上班上的好好的,一个其他部门的同事来着手机来说,APP在他的手机上登录不进去。
实在是最近没有进行升级,在其他手机上也是好好的呀 ~~~
然后他说他以前也是好的,最近手机升级了一次。一查看版本,Android6.0(小米4);
然后测试了一下三星6.0,Nexus6.0的结果都进不去,Android5.0,Android4.0的都
没有问题,所以应该是Android6.0Google对其进行了一些修改。
debug后发现重写的parseNetworkResponse()方法进不去。所以请求网络返回的数据无法解析。
然后跟踪到源码。发现NetworkDispatcher.java这个类里面
进入到了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 {}中