如何在 Android Volley 中判断 TLS 版本

Posted

技术标签:

【中文标题】如何在 Android Volley 中判断 TLS 版本【英文标题】:How do I tell the TLS version in Android Volley 【发布时间】:2015-09-24 23:47:55 【问题描述】:

我的项目长期使用android Volley网络框架,最近发现网上发布的一个SSL 3.0协议bug。

我想知道我的项目使用的 TLS 版本是什么,以及如何确认库是否更新。

这是我的源代码片段:

HttpStack stack = new HurlStack();
Network network = new BasicNetwork(stack);
mHttpRequestQueue = new RequestQueue(new NoCache(), network);
mHttpRequestQueue.start();

我认为重点在于 HurlStack 类,它取决于 org.apache.http 包,但我不知道 TLS/SSL 配置在哪里。

【问题讨论】:

没有 TLS 3.0,我假设你的意思是 SSL 3.0。 @Robert 是的,SSL3 和 TLS1。 我追踪了源代码,只发现了这个:context = SSLContext.getInstance("TLS"); 【参考方案1】:

您可以通过创建自定义 HTTPStack 并在 Volley.java 中的 Volley.newRequestQueue(context, httpStack) 方法中设置堆栈来修改 Volley 中使用的 TLS 版本。虽然,您只需要为 Android 版本 16-19 执行此操作。在 v16 之前,不支持 TLS 1.2,在 v19 之后,默认启用 TLS 1.2。因此,对于 Android 16-19 版本,您应该专注于手动将 TLS 设置为 1.2。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
    && Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) 
    try 
      ProviderInstaller.installIfNeeded(getContext());
     catch (GooglePlayServicesRepairableException e) 
      // Indicates that Google Play services is out of date, disabled, etc.
      // Prompt the user to install/update/enable Google Play services.
      GooglePlayServicesUtil.showErrorNotification(e.getConnectionStatusCode(), getContext());
      // Notify the SyncManager that a soft error occurred.
      syncResult.stats.numIOExceptions++;
      return;
     catch (GooglePlayServicesNotAvailableException e) 
      // Indicates a non-recoverable error; the ProviderInstaller is not able
      // to install an up-to-date Provider.
      // Notify the SyncManager that a hard error occurred.
      syncResult.stats.numAuthExceptions++;
      return;
    

    HttpStack stack = null;
    try 
      stack = new HurlStack(null, new TLSSocketFactory());
     catch (KeyManagementException e) 
      e.printStackTrace();
      Log.d("Your Wrapper Class", "Could not create new stack for TLS v1.2");
      stack = new HurlStack();
     catch (NoSuchAlgorithmException e) 
      e.printStackTrace();
      Log.d("Your Wrapper Class", "Could not create new stack for TLS v1.2");
      stack = new HurlStack();
    
    requestQueue = Volley.newRequestQueue(context, stack);
 else 
  requestQueue = Volley.newRequestQueue(context);

然后使用扩展 SSLSocketFactory 的 TLSSocketFactory 类,就像 Florian Krauthan 在此处创建的那样,其中启用了 v1.2 TLS 协议:https://gist.github.com/fkrauthan/ac8624466a4dee4fd02f#file-tlssocketfactory-java

【讨论】:

在我的 4.4 设备上运行之前,我还必须按照 blog.dev-area.net/2015/08/17/… 升级安全提供程序 @Diederik 的观点非常重要。代码必须处理安全代码提供者的更新。在我的情况下,即使安全提供程序已经被另一个应用程序更新,我仍然必须在我自己的应用程序中包含代码才能使 TLS 工作。 @Ajji 我已经更新了答案,包括检查以确保安全提供商拥有最新的更新。对于那里的其他人,您可以在此处从官方文档中阅读更多信息:developer.android.com/training/articles/… 这可以同步完成(就像我的回答一样)或异步完成。但是,必须这样做。 Android 抱怨 HttpStack 已被弃用。我实现了你的链接的异步版本,它在没有 API 19 的模拟器上的 HttpStack 和 TLSSocketFactory 的情况下工作。跳过那部分可以吗?【参考方案2】:

@w3bshark 的回答对我有用。但使用该代码之前,请确保包含更新Security Provider的代码。就我而言,在我更新安全提供程序之前,TLS 不起作用。以下是更新它的代码。

private void updateAndroidSecurityProvider() 
    try 
        ProviderInstaller.installIfNeeded(this);
     catch (GooglePlayServicesRepairableException e) 
        Log.e("Test321", "PlayServices not installed");
     catch (GooglePlayServicesNotAvailableException e) 
        Log.e("Test321", "Google Play Services not available.");
    

【讨论】:

【参考方案3】:

在 Android 上,使用的 TLS 版本主要取决于使用的 Android 版本。 Apache Volley 基于基于 HttpsUrlConnection 的 Apache Http Client,因此使用了标准的 SSL/TLS SSLSocketFactory。

在低于 4.3 的 Android 上,通常仅支持 SSLv3 和 TLS 1.0。在更高版本中,通常支持但禁用 TLS 1.1 和 1.2。

从 Android 5 开始,TLS 1.1 和 TLS 1.2 是supported and enabled by default

【讨论】:

那在我的源代码中哪里可以找到TLS版本?你能指出它的确切位置吗?我需要完全确认。 只要您不设置自定义 SSLSocketFactory,您的代码就不会指定 TLS 版本。这一切都在 Android API 运行时代码中完成。 应该有一种方法可以为 Android 版本 16-20 的 Volley 启用 TLS v1.2,因为它受支持但默认情况下未启用。您能否向我们指出可能的 Volley 文档?不幸的是,说“这一切都在 Android API 运行时代码中完成”并不是很有帮助。 OkHttp 库提供设置 TLS 版本的功能:***.com/questions/29249630/…

以上是关于如何在 Android Volley 中判断 TLS 版本的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中使用 Volley 库进行肥皂发布请求

如何在Android开发中高效使用Volley网络框架

如何在Android开发中高效使用Volley网络框架

如何使用 Gradle 替换 Android Volley 库?

Android Volley 如何使用 volley 在 POST 请求中发送用户名和密码以及其他参数

如何在 kotlin android 中使用 volley 获取 json