获取 Letsencrypt 证书以使用 android api < 20

Posted

技术标签:

【中文标题】获取 Letsencrypt 证书以使用 android api < 20【英文标题】:Getting Let's encrypt cerificate to work with android api < 20 【发布时间】:2018-02-22 14:11:02 【问题描述】:

我有一个使用 Let's Encrypt CA 的节点服务器,它托管在 zeit.now 上。 客户端是使用 react-native 开发的。 我尝试使用 websockets 连接到它。

ios 和更新的 android 版本 (API > 20) 上,它可以成功连接。

在较旧的 Android 版本(模拟器和实际设备上)上运行时,它永远不会连接。

我尝试使用较旧的 Android 版本连接到未使用 Let's encrypt CA 的服务器(但使用来自其他提供商的 ssl - 托管在 heroku 上),并且它也成功连接。

所以我认为旧的 Android 版本有问题,让我们加密证书。

有人可以帮忙吗?我花了 5 天时间研究这个问题,我对 JAVA 了解不多。

编辑: 我尝试使用 websocket 连接

    ws.onerror = (e) => 
      // an error occurred
      console.log(e.message);
    ;

这个日志:

Connection closed by peer

还有这个方法:

    ws.onclose = (e) => 
      // connection closed
      console.log(e.code, e.reason);
    ;

日志:

undefined, undefined

【问题讨论】:

您可能需要使用证书固定来让您的应用和 Android 知道您使用的证书是可以的。不过,我不是 React Native 开发人员,所以我不知道你有哪些证书固定选项。在更传统的 Android 开发中,您可以使用 OkHttp 对证书固定的支持,或者使用 my backport of Android 7.0+'s network security configuration。 虽然我不太明白什么是证书固定,但我想这意味着 Let's encrypt 证书不被识别为有效?据我所知,React Native 使用的是 Okhttp,因为我可以在这两个文件中看到它:github.com/tuncaulubilge/react-native/blob/…、github.com/tuncaulubilge/react-native/blob/…@Commons "我想这意味着 Let's encrypt 证书不被识别为有效?" -- 我的假设是 Android SDK 和框架类不识别 Let's Encrypt 根证书。 Let's Encrypt 似乎认为他们在 API 级别 11+ 上应该没问题,但他们可能专注于移动浏览器(可以捆绑和使用自己的根证书列表)。我没有尝试从 Android 应用程序访问 Let's Encrypt 服务器,所以我不知道这里到底发生了什么。 这很奇怪,因为当我尝试使用那些旧设备上的浏览器访问服务器时,我能够连接到它。这不是说安卓信任这个证书吗?对不起,如果所有这些都是愚蠢的问题,但这是我第一次参与这些证书。 @CommonsWare 在模拟器中,我使用 Android 19 和 17 成功连接了 Let's Encrypt 证书。但是,问题可能是 TLS 支持。你能发布你得到的堆栈跟踪吗? 【参考方案1】:

我修好了!请参阅此comment。 基本上我需要安装与 Google Play 服务捆绑在一起的最新安全修复程序

【讨论】:

【参考方案2】:

我通过将以下依赖项添加到 Gradle 来解决此问题:

implementation 'com.google.android.gms:play-services-safetynet:17.0.0'

然后调用

public void onCreate() 
    super.onCreate();
    try 
          ProviderInstaller.installIfNeeded(this);
     catch (GooglePlayServicesRepairableException e) 
        // Don't forget exception handling!
     catch (GooglePlayServicesNotAvailableException e) 
        // Do something clever  
    
    SoLoader.init(this, /* native exopackage */ false);
    initializeFlipper(this, getReactNativeHost().getReactInstanceManager());

【讨论】:

以上是关于获取 Letsencrypt 证书以使用 android api < 20的主要内容,如果未能解决你的问题,请参考以下文章

centos7 nigx 免费永久获取 Let‘s Encrypt 证书

如何在 Heroku Node Express 应用程序中使用 LetsEncrypt SSL 证书?

AWS Elastic Beanstalk - NodeJS:在没有 Beanstalk 负载均衡器的情况下从 Letsencrypt 获取证书 SSL

LetsEncrypt 简介

LetsEncrypt 简介

LetsEncrypt 简介