com.android.volley.NoConnectionError:javax.net.ssl.SSLHandshakeException:javax.net.ssl.SSLProtocolException:SSL握手已中止:

时间:2015-08-24 14:26:39

标签: android ssl android-volley

我在我的应用程序中使用Android中的Volley库,当我尝试向我们的服务器发出POST请求时,我收到以下错误:

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

我检查了Cipher over Android启用的密码,他们说它默认启用。

我已经针对这个问题尝试了以下解决方案,但没有一个解决它:

HTTPS support for Volley Android networking library - 不工作(也不适合我,因为它不安全)

How to disable SSLv3 in android for HttpsUrlConnection? - 我试过了,错误仍然存​​在

在项目中使用的Android Api是Android 5.1(API 22)。 Volley库版本是1.0.15(也尝试使用最新版本,1.0.18,但问题仍然存在)。

我尝试过的另一个解决方案是使用与Volley集成的okhttp库,但问题仍然存在。

非常感谢任何有效的解决方案。

提前谢谢!

更新

顺便说一句,我设法从服务器获得支持的密码:

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上的这些密码应该没有问题。

2 个答案:

答案 0 :(得分:17)

我在数小时的互联网和项目代码搜索后发现了这个问题: 在项目内部,我有一个名为JsonRequest<T>的类,它扩展了Volley类setRetryPolicy(new DefaultRetryPolicy(3*DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0)); 。 这是实际为服务器上的每个方法发出请求的类。 在稍微分析一下代码之后,我在构造函数中找到了一个方法调用,如下所示:

DefaultRetryPolicy.DEFAULT_TIMEOUT_MS

其中setRetryPolicy(new DefaultRetryPolicy(5*DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0)); setRetryPolicy(new DefaultRetryPolicy(0, 0, 0)); 设置为2500毫秒。

由于POST请求包含大量数据,因此发送请求并从服务器接收响应需要更多时间。

看起来Volley没有等到响应就来了并抛出了TimeoutError。 因此,请求已经完成,服务器上的一切顺利,但客户端(Android)不等待服务器并且出错。

解决方法是将Timeout参数设置为更高或0,如下所示:

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

剩下的两个问题是:

1)为什么提出请求需要这么长时间? - &GT; 3 * 2500 = 7500ms是一个很长的时间(超过7秒)来发出请求。这不是服务器问题,因为在iOS上它可以正常工作。

2)为什么VolleyError看起来像这样?

{{1}}

应该是TimeoutError而不是NoConnectionError。

您可以在此处找到有关此错误的更多信息,我还推断了解决方案: Android Volley double post when have slow request

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

答案 1 :(得分:0)

解决方案是通过此行代码来增加截击的请求超时。

request.setRetryPolicy(new DefaultRetryPolicy(10 * 1000,0,               DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

以上代码是将设置请求超时设置为10秒。