Android 6.0用https訪問Tomcat服務器時遇到的Handshake failed問題

一、Android6.0的一些修改

因為該問題僅僅出現在Android6.0版本中,因此,考慮是由版本升級引起的。查看Google給出的Android6.0修改文檔,發現以下兩點:

即:

從Android6.0之后將不再支持HttpClient的使用,建議使用HttpURLConnection代替。

Android6.0之后,在Https請求中,SSL層將不再使用OpenSSL協議,改用自己的BoringSSL協議

二、分析

2.1 取消HttpClient

在我們的項目中使用的是HttpClient執行Https請求,但是官方升級只是在API文檔中刪除了HttpClient相關的文件,但是并不影響其使用,用戶可以通過以下兩種方法繼續使用:

使用Android6.0進行編譯,則需要添加 org.apache.http.legacy.jar,文件目錄:SDK\platforms\android-23\optional;或者是在AndroidStudio中的build.gradle文件中加入:

android {useLibrary 'org.apache.http.legacy'}

使用Android6.0以下版本進行編譯。

因此,排除該可能。

2.2 使用BoringSSL替換OpenSSL

因為考慮到是該問題引起的,因此回過頭重新對握手失敗原因進行查看,發現在之前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?。。?/p>

三、解決方案

通過閱讀上邊的文檔,發現兩種可以解決的辦法:

升級JDK到8(條件限制,未經過測試)

配置Tomcat服務器,限制加密方式:

修改Tomcat服務器conf/server.xml文件中和Https有關的Connector節點,添加ciphers用于指定密鑰:

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錯誤。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容