yanzhenjie/NoHttp

发现在一款4.0.4的中兴 ZTE N881E手机上抛出异常,是什么原因?

Closed this issue · 10 comments

java.lang.IllegalArgumentException: protocol TLSv1.1 is not supported

我发起的是不带证书的https请求

具体错误信息:
java.lang.IllegalArgumentException: protocol TLSv1.1 is not supported
at org.apache.harmony.xnet.provider.jsse.NativeCrypto.checkEnabledProtocols(NativeCrypto.java:390)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.setEnabledProtocols(OpenSSLSocketImpl.java:788)
at com.yanzhenjie.nohttpmobilead.ssl.CompatSSLSocketFactory.setSupportProtocolAndCipherSuites(CompatSSLSocketFactory.java:61)
at com.yanzhenjie.nohttpmobilead.ssl.CompatSSLSocketFactory.createSocket(CompatSSLSocketFactory.java:94)
at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:197)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
at com.yanzhenjie.nohttpmobilead.URLConnectionNetworkExecutor.execute(URLConnectionNetworkExecutor.java:102)
at com.yanzhenjie.nohttpmobilead.HttpConnection.createNetwork(HttpConnection.java:169)
at com.yanzhenjie.nohttpmobilead.HttpConnection.createConnectionAndWriteData(HttpConnection.java:122)
at com.yanzhenjie.nohttpmobilead.HttpConnection.getConnection(HttpConnection.java:77)
at com.yanzhenjie.nohttpmobilead.rest.RestProtocol.getHttpProtocol(RestProtocol.java:173)
at com.yanzhenjie.nohttpmobilead.rest.RestProtocol.requestCacheOrNetwork(RestProtocol.java:102)
at com.yanzhenjie.nohttpmobilead.rest.RestProtocol.request(RestProtocol.java:68)
at com.yanzhenjie.nohttpmobilead.rest.SyncRequestExecutor.execute(SyncRequestExecutor.java:41)
at com.yanzhenjie.nohttpmobilead.rest.RequestDispatcher.run(RequestDispatcher.java:96)

不带证书的https请求...

为什么你的报错包名和nohttp的包名不一样?

我是直接把源码拷贝下来,修改了包名的用的,你这边其实有个bug:

private static void setSupportProtocolAndCipherSuites(Socket socket) {
    if (socket instanceof SSLSocket)
        // https://developer.android.com/about/versions/android-5.0-changes.html#ssl
        try {
            ((SSLSocket) socket).setEnabledProtocols(PROTOCOL_ARRAY);
        } catch (Exception e) {
        }
}

这边你没捕捉异常,导致有些手机不支持TLS1.1 1.2时,直接中断了请求

你issue中描述的问题,我目前也没有头绪,我需要研究测试一下,你看看附的链接中是否有解决方案。

问题出现在setEnabledProtocols方法中,方法内有一个checkEnableProtocols方法:
https://android.googlesource.com/platform/libcore/+/android-cts-4.1_r2/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/NativeCrypto.java
上面这是抛出异常的类的源码地址

然后在checkEnableProtocols时 因为手机不支持tls1.1 和1.2 直接就抛出异常了,所以这边得加上try catch

你这样做已经解决你的问题了吗?

对的 解决了

太棒了,谢谢你!:smile:
另外我想推荐一下我新写的Http客户端项目,从框架设计、架构和文档上都比NoHttp更加完善和灵活一点。
地址:https://github.com/yanzhenjie/Kalle

NoHttp也会同时维护,非常感谢提供解决方案。:thumbsup:

利用中午休息的时间认真研究了一下这个问题,写了一段正确的gist到Github:
https://gist.github.com/yanzhenjie/f7217f3fc0f641d9ef50ca0145a7185c

特别说明,SSLv3在Android5.1(Api level21)起默认不启用,从Android8.0(Api level26)起不被支持。TLSv1.1和TLS1.2从Andrid4.1起开始被支持,从Android4.4 Wear(Api level20)起被默认启用。

因此如果你们的应用使用TLSv1.1或者TLSv1.2的话,那么minSdkVersion最小只能是16,如果你们使用TLSv1则暂时没有限制。

参考Google的官方文档:

  1. https://developer.android.com/about/versions/android-5.0-changes.html#ssl
  2. https://developer.android.com/reference/javax/net/ssl/SSLSocket

谢谢了 还是你解决问题犀利