com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: Handshake failed

 上班上的好好的,一个其他部门的同事来着手机来说,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 {}中

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值