安卓能够签署HTTP/HTTPS调用以唯一识别发出请求的应用程序吗?

8

比如说,应用程序的CORS。虽然不是同样的东西,但...

假设我已经上传了一个应用到Play商店,现在我想让我的服务器只接受来自这个应用的连接。

我该怎么办呢?

我期望操作系统能够添加一些过程到我的http请求中,指定市场上应用的ID和在Android链中签署整个请求的签名 -或者在相应的市场CA证书链中进行签名-。然后,我的服务器就可以验证请求是否来自正确的应用程序。

此外,操作系统还可以添加一些认证的硬件信息,以便如果应用程序在模拟器中运行,我也可以拒绝服务。

另一种方法可能是在应用程序中包含一个“秘密”,但它总是可以通过反编译来避开,对吗?或者在https请求发送到服务器时,是否有与Play商店相关联的密钥库可以用来提供这个秘密?

第三种方法可能是使用OAuth登录的azp字段,但它也可能被反编译破解,而且还会强制用户登录。

2个回答

7
假设我已经在应用商店上传了一个应用,现在我想让我的服务器只接受来自此应用的连接。我该如何做?
为了在您的应用程序和API服务器之间实现最高级别的安全性,应当使用移动应用程序认证服务,并与SafetyNet解决方案一起使用,再加上OAUTH2服务以及证书固定,以确保API服务器和移动应用程序之间的通信渠道安全,这些内容在有关移动API技术的这个系列文章中有所介绍。
移动应用程序认证服务的作用是通过在应用程序中集成的SDK和在云中运行的服务,保证运行时您的应用程序没有被篡改或者不是在rooted设备上运行的。
在成功验证应用完整性后,会发出JWT令牌,并使用API服务器和云中的移动应用程序认证服务都知道的密钥进行签名。
如果应用认证失败,则JWT使用API服务器不知道的密钥进行签名。
现在,每次调用API时,应用程序必须在请求头中发送JWT令牌。这将允许API服务器仅在可以验证JWT令牌中的签名并拒绝验证失败时才提供请求。
一旦移动应用程序认证服务使用的密钥不为应用所知,即使应用程序被篡改、在rooted设备上运行或者通过中间人攻击进行通信,也无法在运行时对其进行反向工程。这就是这种服务相较于SafetyNet解决方案的优势。
顺便提一下,如果您的应用程序直接与第三方服务进行通信,则建议将此责任委托给API服务器,这将防止未经授权地代表您使用第三方服务,因为它只会为通过完整性检查的移动应用程序提供真实的请求。
那么为什么不仅使用SafetyNet呢?虽然作为Android新增的安全功能,安全网很好用,但它并不是设计用于成为您应用的唯一安全防御,正如Google自己说的
引用如下:

此 API 的目标是提供有关运行您的应用程序的设备完整性的信心,然后您可以使用标准 Android API 获取附加信号。您应将 SafetyNet Attestation API 用作反滥用系统的一部分的额外深度防御信号,而不是应用程序的唯一反滥用信号。

在我结束前,我想提醒您注意以下内容:
  • 它是Google移动服务(GMS)的一部分,因此只能在拥有此服务的设备上运行。在某些市场,例如远东地区,有大量没有此服务的设备。

  • 标准免费API密钥只能进行有限数量的鉴定调用,因此需要使用(可能是)付费级别来实现规模化使用。

  • 它主要设计用于检查特定Android设备正在运行的操作系统映像是否被认为是安全和兼容的。因此,它可以被认为是相当先进的root检查,能够检查根据文件系统变化指示的已root设备。

  • 由于SafetyNet正在对操作系统映像的哈希进行完整分析,因此它实际上可能会非常慢(有时需要几秒钟)。这意味着它不能持续运行,并且在使用时需要小心隐藏此延迟,但又不会为攻击者利用创造机会。

  • SafetyNet并不专门分析运行应用程序的内存映射以检测仪器框架(它依赖于它们只能在已root设备上运行),例如XPosed和Frida。

  • SafetyNet通过apkDigestSha256功能提供运行应用程序的鉴定。但是,如果未报告完整性,则只能依赖于此。这意味着如果应用程序在任何类型的异常或已root设备上运行,则无法确定应用程序的完整性。一些用户仅出于自定义目的而root其设备,如果移动应用程序中有大量这些用户,则SafetyNet将排除它们无法使用该应用程序。在这种情况下,我们想要了解正在运行的应用程序的完整性而不是整个系统的完整性。SafetyNet无法做到这一点,但是移动应用程序鉴定服务可以。

  • 为了以无法欺骗的方式执行鉴定检查,则应用程序不能进行自己的检查(因为显然此代码本身可能被篡改)。因此,需要实现服务器端以可靠地使用该功能。


2
使用Safety Net Attestation流程向服务器请求一个秘密令牌。
阅读相关问题后,我认为诀窍是使用Safety Net流程:
  • 使用SafetyNet Attestation API,应用程序可以从Android服务获取签名的JSON。
  • 应用程序从android_id、随机UUID或两者生成一些ID。
  • 将ID和JSON都发送到服务器,服务器可以验证请求来自真实的应用程序,保存ID和配置数据,并同意进一步通信的令牌。
  • 使用keychain api,应用程序将ID和令牌保存在keystore中以供将来使用。
这是一个推测性的答案(我是OP),请只在您确定其正确且没有更好的替代方案时投票支持它。

Attestation Flow, from Android documentation


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接