在Android 5.0 Lollipop中,DefaultHttpClient似乎存在问题。它无法连接一些之前版本的Android已成功连接的网站。
例如,我尝试连接到https://uralsg.megafon.ru
//Create httpclient like in https://dev59.com/eHbZa4cB1Zd3GeqPD0eZ
HttpClient client = new DefaultHttpClient(manager, params);
HttpGet httpGet = new HttpGet("https://uralsg.megafon.ru");
HttpResponse client = httpclient.execute(httpGet);
这段代码在Android 2.3-4.4上能够正常工作,但在Android 5.0上(包括模拟器和设备)因为出现了“Connection closed by peer”错误而无法使用。
显然这是可以理解的,因为Android 5.0尝试使用TLSv1.2和现代密码算法连接这个旧服务器,而这些协议和算法并不被支持。
好的,我们参考SSL/TLS protocols and cipher suites with the AndroidHttpClient中的示例代码,将协议和密码限制为和。现在它出现了不同的错误:
javax.net.ssl.SSLHandshakeException: Handshake failed
caused by
error:140943FC:SSL routines:SSL3_READ_BYTES:sslv3 alert bad record mac
(external/openssl/ssl/s3_pkt.c:1286 0x7f74c1ef16e0:0x00000003)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake
当然,这段代码在Android 2.3-4.4上运行顺畅。
我使用wireshark检查了流量:
302 4002.147873000 192.168.156.30 83.149.32.13 TLSv1 138 Client Hello
303 4002.185362000 83.149.32.13 192.168.156.30 TLSv1 133 Server Hello
304 4002.186700000 83.149.32.13 192.168.156.30 TLSv1 1244 Certificate
305 4002.186701000 83.149.32.13 192.168.156.30 TLSv1 63 Server Hello Done
307 4002.188117000 192.168.156.30 83.149.32.13 TLSv1 364 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
308 4002.240695000 83.149.32.13 192.168.156.30 TLSv1 61 Alert (Level: Fatal, Description: Bad Record MAC)
您可以看到连接已经建立,但是服务器报警,因为它可能无法解码加密的握手消息。
我无法使用 Android 5.0 上的 HttpClient 连接 https://uralsg.megafon.ru。然而,股票浏览器确实可以连接它。Android 2.3-4.4 可以以任何方式连接此站点而无需任何困难。
是否有办法使 HttpClient 能够连接这样的网站?这只是一个例子,我相信还有很多传统服务器无法通过 Android 5.0 和 HttpClient 连接。