【问题标题】:Provide private key and certificate for android app为安卓应用提供私钥和证书
【发布时间】:2021-05-07 15:04:29
【问题描述】:

我的应用需要使用网络服务,我想通过证书对服务器进行应用验证。

但是,将带有签名密钥的密钥库嵌入包中被认为是不好的做法(并明确警告:https://developer.android.com/google/play/asi),因为它可以被提取并解密。

我可以使用 android 提供的密钥库生成私钥并使用它 - 但我仍然需要对其进行签名以便在服务器端对其进行验证。

在理想情况下,应该有证书链,具有受信任的根授权并包含我可以在服务器端验证的签名应用程序包的元数据。

或者是否有可能在证书生成过程中使用包签名来证明自签名证书源自未篡改的包?

【问题讨论】:

  • 您是否要进行证书固定?还是这有什么不同?
  • 否 - 我尝试为应用程序提供可用于身份验证的私钥和证书,而无需将密钥库存储在 apk 存档中。
  • 好的,只是确保这不是一回事,我没有大量的证书固定经验,但听起来很熟悉,所以只是想确保它不相关跨度>
  • 对不起,如果我听起来很菜鸟,但为什么要使用证书?我的意思是,证书(另外 pinning )不是为了让客户端验证他们正在向真实服务器而不是 MIM 发出请求,而不是其他方式。为什么不能使用某种授权技术,如密钥、承载和刷新令牌?再次抱歉新手评论)
  • 通常客户端使用服务器证书来验证服务器是否真实(它使用适当的权限链签名,并且客户端信任此权限)。最常见的用例。并且服务器也可以以其他方式使用相同的技术 - 客户端提供由适当权限保护的公钥,以针对服务器验证自己。在我的用例中,服务器对客户端密钥有明确的了解(自签名证书放置在服务器端的信任库中) - 因此双方都可以建立正确的 TLS 连接并信任它。

标签: android ssl certificate keystore signing


【解决方案1】:

不良行为者(“Trudy”)可以刷写任何自定义 Android ROM,包括在 APK 安装期间删除包证书验证的 ROM。因此,您的应用对其 Android 主机操作系统的任何查询本质上都是对 Trudy 的请求。

因此,有可能发现安装了带有纯正操作系统的被黑 APK。但是对于掺假的操作系统,所有的赌注都没有了。

我认为客户端进行自我验证的任何解决方案都需要对主机操作系统进行权威验证。不容易。

是否可以在证书中使用包签名 证明自签名证书起源的生成过程 形成未篡改的包裹?

(1) 你的意思是每个客户端在安装后生成不同的自签名证书,并以某种方式将其与 apk 包签名交叉引用以进行身份​​验证?那么不,这不会阻止特鲁迪。 (而且它在身份验证中也没有用处。)

(2) 你的意思是客户端在 APK 中嵌入了一个通用私钥,并且可以使用包证书上的元数据来验证私钥吗?我不知道包证书元数据中是否有任何可用字段可以添加此信息。这是您建议的一种有趣的方法。然而,由于 Trudy 可能是操作系统,理论上 Trudy 可以模拟它想要的任何结果。我认为这不会阻止 Trudy。

这个 (SO) 的 Proguard 开发人员发布的帖子提供了 5 个选项来处理您的 Android 应用程序中的机密信息。他指出:

本质上,客户端没有什么是牢不可破的,但你可以 肯定会提高标准。

【讨论】:

  • 我查看了从包管理器返回的签名,但像 CN 这样的大多数字段都是伪造的(我假设在真实设备上会有更有意义的东西) - 但因为它可以从 APK 中提取,所以这不是好秘密。悬停我有另一个想法隐藏密钥库密码 - 在代码中的其他地方组装它并使用反射在某个随机时间在内存中的特定位置提供它。这肯定会提高标准。
  • @KonstantinPribluda 使用反射的想法很有趣,我链接到的方法之一会涵盖该方法吗?
【解决方案2】:

我了解您希望使用用户的私钥对 Web 服务 (API) 进行用户身份验证,并且签名令牌将在服务器上使用用户注册时已注册的用户证书或公钥进行验证。

您是希望使用外部 USB 令牌安全地存储私钥还是要将私钥存储在 Android 设备内存中?

我们已经在台式机(https://web.signer.digital/Home 的示例)上解决了此类要求,但在 Android 上没有。我知道我们可以使用 OTG USB 将 USB 加密令牌(如 ePass2003 或其他)连接到 Android 设备,并且某些设备的 Android 驱动程序可以从 Android 访问,但实际上并没有使用它。但这可以作为您研究的方向。

【讨论】:

  • 不完全。我想在没有任何用户交互的情况下验证我的应用程序。并使其合理地防篡改。外部(应用程序)令牌超出了范围 - 我正在寻找自包含的解决方案。
【解决方案3】:

移动应用程序是公共应用程序,因为最终用户可能会查看和修改应用程序代码。因此,您的应用程序无法对恶意用户保密。这包括客户端证书,这是双向 TLS (mTLS) 所必需的。

在 Android 设备上存储任何客户端证书以供机器对机器(不要将 machine to machineuser to machine 混合使用)mTLS 身份验证是不安全的。它可以被任何用户导出并在其他设备上使用。

操作系统(Android 以及某些浏览器,例如 Firefox 可能有自己的)提供证书存储,CA 证书存储在哪里,客户端证书可以存储在哪里。

在此处存储用户(为用户颁发,而不是为应用程序/机器颁发)客户端证书是个好主意。然后移动应用程序应该有一个选项来选择哪些用户客户端证书应该用于 mTLS。但是I want to authenticate my application without any user interaction. 是不可能的。必须至少有初始用户交互:用户客户端证书导入到客户端存储、mTLS 应用程序配置。恕我直言,这是最好和最安全的 mTLS 实施。真实世界示例:Rocket Chat app

【讨论】:

    【解决方案4】:

    您要求基于反向 TLS 的验证?通常,客户端会验证 Web 服务,因为客户端的主机操作系统信任特定的 CA 证书,该证书也用于生成 Web 服务 TLS 证书。

    区别在于:

    网络服务器由作者保护和控制。客户端设备不是。因此,在应用程序中使用私钥对发送到服务器的数据进行签名是徒劳的。

    不过,您可以通过服务器端验证探索 Google's Licensing implementation,以强制合法安装和许可的应用可以联系服务器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-08
      • 2016-11-22
      • 2016-02-17
      • 1970-01-01
      • 2020-01-17
      • 2011-11-03
      • 1970-01-01
      • 2018-04-25
      相关资源
      最近更新 更多