我正在開發一個應用程序,用戶必須爲其設置自己的服務器(即nginx)來運行後端應用程序。需要在應用程序中配置相應的域以便連接。我一直在我自己的手機上進行測試(索尼z3c),並開始爲5.1開發。後來我收到了6.0版的更新,但仍在仿真器中保持工作狀態5.1。不久之前,我開始使用7.0版本的AVD工作,並且驚訝地發現它不會連接到我的服務器,告訴我ssl握手失敗。我的nginx配置非常嚴格,但它適用於5.1和6.0,所以....?!SSLHandshakeException:握手在Android N/7.0上失敗
這是我所知道的:
- 我使用V24支持庫,即我的compileSdkVersion爲24
- 我使用排v1.0.0。
- 我試過TLSSocketFactory,但它沒有改變任何東西。這似乎在大多數情況下被用於防止老版本的SDK版本使用SSL3。
- 我試過增加timeout,但它沒有改變任何東西。
- 我試過直接使用HttpURLConnection,但它並沒有改變任何東西除了堆棧跟蹤(它沒有排除引用,但其他相同)。
如果沒有TLSSocketFactory,請求將通過一個裸請求隊列進行,該請求隊列使用Volley.newRequestQueue(context)
實例化。
這是我在Android Studio中看到:
W/System.err: com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: Connection closed by peer
W/System.err: at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:151)
W/System.err: at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:112)
W/System.err: Caused by: javax.net.ssl.SSLHandshakeException: Connection closed by peer
W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
W/System.err: at com.android.okhttp.Connection.connectTls(Connection.java:235)
W/System.err: at com.android.okhttp.Connection.connectSocket(Connection.java:199)
W/System.err: at com.android.okhttp.Connection.connect(Connection.java:172)
W/System.err: at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:367)
W/System.err: at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:130)
W/System.err: at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
W/System.err: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:246)
W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:126)
W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:257)
W/System.err: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
W/System.err: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java)
W/System.err: at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:264)
W/System.err: at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:234)
W/System.err: at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:107)
W/System.err: at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
W/System.err: ... 1 more
W/System.err: Suppressed: javax.net.ssl.SSLHandshakeException: Handshake failed
W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:429)
W/System.err: ... 17 more
W/System.err: Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x7ffef3748040: Failure in SSL library, usually a protocol error
W/System.err: error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE (external/boringssl/src/ssl/s3_pkt.c:610 0x7ffeda1d2240:0x00000001)
W/System.err: error:1000009a:SSL routines:OPENSSL_internal:HANDSHAKE_FAILURE_ON_CLIENT_HELLO (external/boringssl/src/ssl/s3_clnt.c:764 0x7ffee9d2b70a:0x00000000)
W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
W/System.err: ... 17 more
因爲它說SSLV3_ALERT_HANDSHAKE_FAILURE
由於某種原因,嘗試使用SSLv3的連接和失敗我只能假設,但這樣做沒有任何意義,我任何。這可能是一個密碼問題,但我怎麼知道它試圖使用什麼?我寧願不啓用服務器上的密碼,進行連接嘗試並重復。
我nginx的網站使用的是咱們加密證書,並具有以下配置:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/ssl/certs/lets-encrypt-x1-cross-signed.pem;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:!aNULL;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2;
爲了測試這些密碼我有一個script,它證實了這些密碼(在喘息VPS服務器的網絡外運行) :
Testing ECDHE-RSA-AES256-GCM-SHA384...YES Testing ECDHE-ECDSA-AES256-GCM-SHA384...NO (sslv3 alert handshake failure) Testing ECDHE-RSA-AES256-SHA384...NO (sslv3 alert handshake failure) Testing ECDHE-ECDSA-AES256-SHA384...NO (sslv3 alert handshake failure) Testing ECDHE-RSA-AES256-SHA...NO (sslv3 alert handshake failure) Testing ECDHE-ECDSA-AES256-SHA...NO (sslv3 alert handshake failure) Testing SRP-DSS-AES-256-CBC-SHA...NO (sslv3 alert handshake failure) Testing SRP-RSA-AES-256-CBC-SHA...NO (sslv3 alert handshake failure) Testing DHE-DSS-AES256-GCM-SHA384...NO (sslv3 alert handshake failure) Testing DHE-RSA-AES256-GCM-SHA384...NO (sslv3 alert handshake failure) Testing DHE-RSA-AES256-SHA256...NO (sslv3 alert handshake failure) Testing DHE-DSS-AES256-SHA256...NO (sslv3 alert handshake failure) Testing DHE-RSA-AES256-SHA...NO (sslv3 alert handshake failure) Testing DHE-DSS-AES256-SHA...NO (sslv3 alert handshake failure) Testing DHE-RSA-CAMELLIA256-SHA...NO (sslv3 alert handshake failure) Testing DHE-DSS-CAMELLIA256-SHA...NO (sslv3 alert handshake failure) Testing AECDH-AES256-SHA...NO (sslv3 alert handshake failure) Testing SRP-AES-256-CBC-SHA...NO (sslv3 alert handshake failure) Testing ADH-AES256-GCM-SHA384...NO (sslv3 alert handshake failure) Testing ADH-AES256-SHA256...NO (sslv3 alert handshake failure) Testing ADH-AES256-SHA...NO (sslv3 alert handshake failure) Testing ADH-CAMELLIA256-SHA...NO (sslv3 alert handshake failure) Testing ECDH-RSA-AES256-GCM-SHA384...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-AES256-GCM-SHA384...NO (sslv3 alert handshake failure) Testing ECDH-RSA-AES256-SHA384...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-AES256-SHA384...NO (sslv3 alert handshake failure) Testing ECDH-RSA-AES256-SHA...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-AES256-SHA...NO (sslv3 alert handshake failure) Testing AES256-GCM-SHA384...NO (sslv3 alert handshake failure) Testing AES256-SHA256...NO (sslv3 alert handshake failure) Testing AES256-SHA...NO (sslv3 alert handshake failure) Testing CAMELLIA256-SHA...NO (sslv3 alert handshake failure) Testing PSK-AES256-CBC-SHA...NO (no ciphers available) Testing ECDHE-RSA-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing ECDHE-ECDSA-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing SRP-DSS-3DES-EDE-CBC-SHA...NO (sslv3 alert handshake failure) Testing SRP-RSA-3DES-EDE-CBC-SHA...NO (sslv3 alert handshake failure) Testing EDH-RSA-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing EDH-DSS-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing AECDH-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing SRP-3DES-EDE-CBC-SHA...NO (sslv3 alert handshake failure) Testing ADH-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing ECDH-RSA-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing DES-CBC3-SHA...NO (sslv3 alert handshake failure) Testing PSK-3DES-EDE-CBC-SHA...NO (no ciphers available) Testing ECDHE-RSA-AES128-GCM-SHA256...YES Testing ECDHE-ECDSA-AES128-GCM-SHA256...NO (sslv3 alert handshake failure) Testing ECDHE-RSA-AES128-SHA256...NO (sslv3 alert handshake failure) Testing ECDHE-ECDSA-AES128-SHA256...NO (sslv3 alert handshake failure) Testing ECDHE-RSA-AES128-SHA...NO (sslv3 alert handshake failure) Testing ECDHE-ECDSA-AES128-SHA...NO (sslv3 alert handshake failure) Testing SRP-DSS-AES-128-CBC-SHA...NO (sslv3 alert handshake failure) Testing SRP-RSA-AES-128-CBC-SHA...NO (sslv3 alert handshake failure) Testing DHE-DSS-AES128-GCM-SHA256...NO (sslv3 alert handshake failure) Testing DHE-RSA-AES128-GCM-SHA256...NO (sslv3 alert handshake failure) Testing DHE-RSA-AES128-SHA256...NO (sslv3 alert handshake failure) Testing DHE-DSS-AES128-SHA256...NO (sslv3 alert handshake failure) Testing DHE-RSA-AES128-SHA...NO (sslv3 alert handshake failure) Testing DHE-DSS-AES128-SHA...NO (sslv3 alert handshake failure) Testing DHE-RSA-SEED-SHA...NO (sslv3 alert handshake failure) Testing DHE-DSS-SEED-SHA...NO (sslv3 alert handshake failure) Testing DHE-RSA-CAMELLIA128-SHA...NO (sslv3 alert handshake failure) Testing DHE-DSS-CAMELLIA128-SHA...NO (sslv3 alert handshake failure) Testing AECDH-AES128-SHA...NO (sslv3 alert handshake failure) Testing SRP-AES-128-CBC-SHA...NO (sslv3 alert handshake failure) Testing ADH-AES128-GCM-SHA256...NO (sslv3 alert handshake failure) Testing ADH-AES128-SHA256...NO (sslv3 alert handshake failure) Testing ADH-AES128-SHA...NO (sslv3 alert handshake failure) Testing ADH-SEED-SHA...NO (sslv3 alert handshake failure) Testing ADH-CAMELLIA128-SHA...NO (sslv3 alert handshake failure) Testing ECDH-RSA-AES128-GCM-SHA256...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-AES128-GCM-SHA256...NO (sslv3 alert handshake failure) Testing ECDH-RSA-AES128-SHA256...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-AES128-SHA256...NO (sslv3 alert handshake failure) Testing ECDH-RSA-AES128-SHA...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-AES128-SHA...NO (sslv3 alert handshake failure) Testing AES128-GCM-SHA256...NO (sslv3 alert handshake failure) Testing AES128-SHA256...NO (sslv3 alert handshake failure) Testing AES128-SHA...NO (sslv3 alert handshake failure) Testing SEED-SHA...NO (sslv3 alert handshake failure) Testing CAMELLIA128-SHA...NO (sslv3 alert handshake failure) Testing PSK-AES128-CBC-SHA...NO (no ciphers available) Testing ECDHE-RSA-RC4-SHA...NO (sslv3 alert handshake failure) Testing ECDHE-ECDSA-RC4-SHA...NO (sslv3 alert handshake failure) Testing AECDH-RC4-SHA...NO (sslv3 alert handshake failure) Testing ADH-RC4-MD5...NO (sslv3 alert handshake failure) Testing ECDH-RSA-RC4-SHA...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-RC4-SHA...NO (sslv3 alert handshake failure) Testing RC4-SHA...NO (sslv3 alert handshake failure) Testing RC4-MD5...NO (sslv3 alert handshake failure) Testing PSK-RC4-SHA...NO (no ciphers available) Testing EDH-RSA-DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing EDH-DSS-DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing ADH-DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing EXP-EDH-RSA-DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing EXP-EDH-DSS-DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing EXP-ADH-DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing EXP-DES-CBC-SHA...NO (sslv3 alert handshake failure) Testing EXP-RC2-CBC-MD5...NO (sslv3 alert handshake failure) Testing EXP-ADH-RC4-MD5...NO (sslv3 alert handshake failure) Testing EXP-RC4-MD5...NO (sslv3 alert handshake failure) Testing ECDHE-RSA-NULL-SHA...NO (sslv3 alert handshake failure) Testing ECDHE-ECDSA-NULL-SHA...NO (sslv3 alert handshake failure) Testing AECDH-NULL-SHA...NO (sslv3 alert handshake failure) Testing ECDH-RSA-NULL-SHA...NO (sslv3 alert handshake failure) Testing ECDH-ECDSA-NULL-SHA...NO (sslv3 alert handshake failure) Testing NULL-SHA256...NO (sslv3 alert handshake failure) Testing NULL-SHA...NO (sslv3 alert handshake failure) Testing NULL-MD5...NO (sslv3 alert handshake failure
我可以打開模擬器的瀏覽器服務器的URL並獲得一個完美的JSON響應,所以我知道系統本身能。
所以問題是,爲什麼我不能在Android 7上連接?
更新:
我已經看了使用tcpdump和Wireshark的捕獲的數據包,並啓用密碼是在客戶問候,所以這不應該是一個問題。
Cipher Suites (18 suites) Cipher Suite: Unknown (0xcca9) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) Cipher Suite: Unknown (0xcca8) Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) Cipher Suite: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009e) Cipher Suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009) Cipher Suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a) Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) Cipher Suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Cipher Suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033) Cipher Suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039) Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009c) Cipher Suite: TLS_RSA_WITH_AES_256_GCM_SHA384 (0x009d) Cipher Suite: TLS_RSA_WITH_AES_128_CBC_SHA (0x002f) Cipher Suite: TLS_RSA_WITH_AES_256_CBC_SHA (0x0035)
正如你可以看到0xc02f
和0xc030
比賽,但接下來的TLSv1.2工作包說:Alert (21), Handshake Failure (40)
。
更新2:
這些是從5.1的Android曲線中的ClientHello:
Elliptic curves (25 curves) Elliptic curve: sect571r1 (0x000e) Elliptic curve: sect571k1 (0x000d) Elliptic curve: secp521r1 (0x0019) Elliptic curve: sect409k1 (0x000b) Elliptic curve: sect409r1 (0x000c) Elliptic curve: secp384r1 (0x0018) Elliptic curve: sect283k1 (0x0009) Elliptic curve: sect283r1 (0x000a) Elliptic curve: secp256k1 (0x0016) Elliptic curve: secp256r1 (0x0017) Elliptic curve: sect239k1 (0x0008) Elliptic curve: sect233k1 (0x0006) Elliptic curve: sect233r1 (0x0007) Elliptic curve: secp224k1 (0x0014) Elliptic curve: secp224r1 (0x0015) Elliptic curve: sect193r1 (0x0004) Elliptic curve: sect193r2 (0x0005) Elliptic curve: secp192k1 (0x0012) Elliptic curve: secp192r1 (0x0013) Elliptic curve: sect163k1 (0x0001) Elliptic curve: sect163r1 (0x0002) Elliptic curve: sect163r2 (0x0003) Elliptic curve: secp160k1 (0x000f) Elliptic curve: secp160r1 (0x0010) Elliptic curve: secp160r2 (0x0011)
在服務器問候secp384r1 (0x0018)
被返回。
這是從Android的7:
Elliptic curves (1 curve) Elliptic curve: secp256r1 (0x0017)
在握手故障而導致的。
通過刪除secp384r1或將其替換爲默認值(prime256v1)來更改nginx配置會使其工作。所以我想這個問題仍然存在:我能夠添加橢圓曲線嗎?
使用模擬器時的捕獲數據與使用Android 7.0設備(通用移動4G)時相同。
更新3:
小更新,但值得一提的:我把它用在模擬器上工作的Android 7.1.1(!)。它示出了如下的數據(再次使用tcpdump的抓住和使用Wireshark的觀察):
Elliptic curves (3 curves) Elliptic curve: secp256r1 (0x0017) Elliptic curve: secp384r1 (0x0018) Elliptic curve: secp512r1 (0x0019)
它顯示了相同的18個密碼套件。
「我可以在模擬器中的瀏覽器中打開服務器的URL」 - 最有可能的,該瀏覽器不使用HTTP連接Java代碼,所以這只是一個局部測試。網絡,特殊的SSL處理,在Android 7.0中進行了相當大的改革,以支持[網絡安全配置](https://developer.android.com/training/articles/security-config.html)。您是否依賴用戶證書(即用戶通過設置添加的證書)? – CommonsWare
我認爲你的服務器配置可能有點太嚴格。 tt只允許一條曲線和兩條密碼。 Wireshark中的連接和分析的數據包捕獲將顯示ClientHello中客戶端提供哪些密碼和曲線,以便您可以檢查客戶端是否也支持您的服務器支持。不必太在意「** sslv3 **握手失敗」 - 當使用TLS 1.2時,您也會得到這個,因爲協議在這個區域基本相同,因此它從sslv3重用了使用奇怪錯誤消息的功能。 –
@CommonsWare:我不依賴於用戶證書,不。 – Cornelis