因为微信的公众号和小程序开发须要https,在使用过程当中发现Android6.0版本手机接口请求老是失败,在细查之下发现跟https的证书有关,下面的方案通过验证可行,转过来看下;android
原博客:https://blog.csdn.net/duanbokan/article/details/50911148算法
Android6.0版本的,升级后,在测试咱们的应用时,忽然出现握手失败错误:apache
可是在Android6.0如下版本中,并无出现该问题。小程序
由于该问题仅仅出如今Android6.0版本中,所以,考虑是由版本升级引发的。查看Google给出的Android6.0修改文档,发现如下两点:tomcat
即:安全
在咱们的项目中使用的是HttpClient执行Https请求,可是官方升级只是在API文档中删除了HttpClient相关的文件,可是并不影响其使用,用户能够经过如下两种方法继续使用:bash
使用Android6.0进行编译,则须要添加 org.apache.http.legacy.jar,文件目录:SDK\platforms\android-23\optional;或者是在AndroidStudio中的build.gradle文件中加入:服务器
android {useLibrary 'org.apache.http.legacy'
}微信
使用Android6.0如下版本进行编译。测试
所以,排除该可能。
由于考虑到是该问题引发的,所以回过头从新对握手失败缘由进行查看,发如今以前Log结尾部分忽略了一句话,也正是由于忽略这句话,致使以前思惟一直停在多是HttpClient被取消致使的,浪费了不少时间,握手失败后,在最后边Log中,出现这样的信息:
关键字:BAD_DH_P_LENGTH
通过一番寻找,发现意思应该是Diffie-Hellman的p参数长度错误。主要参考文章:谢谢大神——链接
经过对帖子的阅读和资料的查找,总结其主要缘由在于:
Https创建链接以前,会进行屡次握手,即单向认证和双向认证。在该过程当中,客户端会将本身支持的全部加密方式发送给服务端,供服务端选择,服务端选择好加密程度较高的加密方式后,会以明文或者是客户端私钥加密密文的方式发送给客户端。
具体认证过程可参考个人上一篇文章:Https单向认证和双向认证
在握手过程当中,一定会涉及到公钥加密,私钥解密的过程,而该过程当中,当服务端选择使用诸如TLS_DHE_RSA_WITH_AES_128_CBC_SHA
等算法进行加密时,须要使用到Diffie-Hellman算法进行加密解密,经过阅读Diffie-Hellman算法的介绍,发如今加密解密计算过程当中,会使用到两个参数,一个是q,一个是a,而在JDK8以前,服务器端提供的q参数只是用了768bit的长度,而不足1024bit则存在相应的安全漏洞,会被替换后的BroingSSL拒绝,所以出现了Handshake failed错误。
终于找到问题所在了,总结这个纠结的过程,我只想说:必定要认真看Log!!!
经过阅读上边提到的大神写的帖子,发现两种能够解决的办法:
升级JDK到8(条件限制,未通过测试)
配置Tomcat服务器,限制加密方式:
修改Tomcat服务器conf/server.xml文件中和Https有关的Connector节点,添加ciphers用于指定密钥:
<Connector
SSLEnabled="true"
clientAuth="false"
connectionTimeout="20000"
keystoreFile="/usr/xinwei/tienlen/apache-tomcat-https/server.keystore"
keystorePass="xinwei"
maxThreads="150"
port="443"
protocol="org.apache.coyote.http11.Http11Protocol"
redirectPort="8443"
scheme="https"
secure="true"
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"
sslProtocol="TLS"
truststoreFile="/usr/xinwei/tienlen/apache-tomcat-https/server.keystore"
truststorePass="密码"
/>
复制代码
添加完该配置后,重启,测试,Android6.0版本没有再发现Handshake failed错误。