2015-08-24 88 views
5

我在我的應用程序中使用Android中的Volley庫,並嘗試向POST請求發送我們的服務器出現以下錯誤:com.android.volley.NoConnectionError:javax.net.ssl.SSLHandshakeException:javax.net.ssl.SSLProtocolException:SSL握手中止:

com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6821edb0: Failure in SSL library, usually a protocol error 
error:1407743E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert inappropriate fallback (external/openssl/ssl/s23_clnt.c:744 0x5f4c0c46:0x00000000) 

我們的服務器與下面的SSL證書籤名:

i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA 
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA 
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority 
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority 
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root 

證書由OpenSSL的描述如下:

New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA 

我檢查了啓用Android的Cipher密碼,他們說默認啓用。

我已經嘗試了這個問題,下面的解決方案,但他們沒有解決它:

HTTPS support for Volley Android networking library - 不工作(也不太適合我,因爲它並不安全)

How to disable SSLv3 in android for HttpsUrlConnection? - 我已經試過這個錯誤仍然發生

out項目中使用的Android Api是Android 5.1(API 22)。 Volley庫版本是1.0.15(也嘗試了最新的1.0.18,但問題仍然存在)。

我試過的另一個解決方案是使用與Volley集成的okhttp庫,但問題仍然存在。

任何工作解決方案將不勝感激。

預先感謝您!

UPDATE

順便說一句,我設法從服務器獲取支持的密碼:

Supported cipher suites (ORDER IS NOT SIGNIFICANT): 
    SSLv3 
    RSA_WITH_RC4_128_MD5 
    RSA_WITH_RC4_128_SHA 
    RSA_WITH_IDEA_CBC_SHA 
    RSA_WITH_3DES_EDE_CBC_SHA 
    DHE_RSA_WITH_3DES_EDE_CBC_SHA 
    RSA_WITH_AES_128_CBC_SHA 
    DHE_RSA_WITH_AES_128_CBC_SHA 
    RSA_WITH_AES_256_CBC_SHA 
    DHE_RSA_WITH_AES_256_CBC_SHA 
    RSA_WITH_CAMELLIA_128_CBC_SHA 
    DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 
    RSA_WITH_CAMELLIA_256_CBC_SHA 
    DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 
    TLS_RSA_WITH_SEED_CBC_SHA 
    TLS_DHE_RSA_WITH_SEED_CBC_SHA 
    (TLSv1.0: idem) 
    (TLSv1.1: idem) 
    TLSv1.2 
    RSA_WITH_RC4_128_MD5 
    RSA_WITH_RC4_128_SHA 
    RSA_WITH_IDEA_CBC_SHA 
    RSA_WITH_3DES_EDE_CBC_SHA 
    DHE_RSA_WITH_3DES_EDE_CBC_SHA 
    RSA_WITH_AES_128_CBC_SHA 
    DHE_RSA_WITH_AES_128_CBC_SHA 
    RSA_WITH_AES_256_CBC_SHA 
    DHE_RSA_WITH_AES_256_CBC_SHA 
    RSA_WITH_AES_128_CBC_SHA256 
    RSA_WITH_AES_256_CBC_SHA256 
    RSA_WITH_CAMELLIA_128_CBC_SHA 
    DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 
    DHE_RSA_WITH_AES_128_CBC_SHA256 
    DHE_RSA_WITH_AES_256_CBC_SHA256 
    RSA_WITH_CAMELLIA_256_CBC_SHA 
    DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 
    TLS_RSA_WITH_SEED_CBC_SHA 
    TLS_DHE_RSA_WITH_SEED_CBC_SHA 
    TLS_RSA_WITH_AES_128_GCM_SHA256 
    TLS_RSA_WITH_AES_256_GCM_SHA384 
    TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 
    TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 

從我讀,應該有與API LVL 22這些密碼沒有問題。

+0

被添加到設備上的受信任的證書列表中選擇您的證書? –

+0

如上所述,我檢查了密碼(DHE-RSA-AES256-SHA),Android表示它在默認情況下在API級別22中是enebled。此外,證書是CA可信的,所以它應該可以在所有設備上工作,並且不需要將其專門添加到應用程序 –

+0

我希望您可以在[Android 5.0行爲更改 - TLS/SSL默認配置更改]中找到解決方案(http://developer.android.com/about/versions/android-5.0-changes .html#ssl) – BNK

回答

16

我經過幾個小時搜索互聯網和項目代碼後發現問題: 在項目中我有一個名爲JsonToPOJORequest<T>的類,它擴展了Volley cla ss JsonRequest<T>。 這是實際爲服務器上的每個方法發出請求的類。 分析代碼一點點後,我發現裏面的構造方法調用,如下所示:

setRetryPolicy(new DefaultRetryPolicy(3*DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0)); 

其中DefaultRetryPolicy.DEFAULT_TIMEOUT_MS設置爲2500毫秒。

由於POST請求包含大量數據,因此需要更多時間來發送請求並從服務器接收響應。

似乎Volley沒有等待足夠的響應來引發TimeoutError。 因此,請求已完成,服務器上的所有內容都會正常工作,但客戶端(Android)不會等待服務器併發生錯誤。

解決的辦法是設置超時參數,以高於或0,像這樣:

setRetryPolicy(new DefaultRetryPolicy(5*DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0)); 
setRetryPolicy(new DefaultRetryPolicy(0, 0, 0)); 

仍然存在的兩個問題是:

1)爲什麼要花這麼長的時間提出要求? - > 3 * 2500 = 7500ms需要很長時間(超過7秒)才能提出請求。這不是服務器問題,因爲在iOS上它工作得很好。

2)爲什麼VolleyError看起來像這樣?

com.android.volley.NoConnectionError: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: 

應該是TimeoutError而不是NoConnectionError。

你可以找到更多有關這個錯誤在這裏,是我還推導出的解決方案: Android Volley double post when have slow request

https://groups.google.com/forum/#!topic/volley-users/8PE9dBbD6iA

+0

req.setRetryPolicy(new DefaultRetryPolicy(0,-1,0)); 這是我的工作 –