为应用添加服务器端许可验证

验证用户是否已从 Google Play 商店购买或下载应用的合法副本时,最好在您控制的服务器上执行许可验证检查。

本指南介绍了完成服务器端许可验证的分步流程,并介绍了与执行此项检查相关的一些最佳做法。

流程概览

图 1 显示了应用、Google Play 和私有服务器之间如何传输信息:

数据流程图
图 1. 应用与 Google Play 之间以及应用与私有服务器之间的数据流
  1. 应用向 Google Play 发出请求,询问特定用户是否已购买或下载应用的合法副本。
  2. Google Play 会通过向应用发送响应数据对象(对象类型为 ResponseData)来做出响应。此对象是一条签名信息,表明用户是否已购买或下载应用的合法副本。
  3. 应用向您控制的私有服务器发出请求,以验证响应数据的内容。
  4. 服务器通过向应用发送状态来做出响应,以指示用户是否确实已购买或下载应用的合法副本。如果服务器提供“成功”消息,验证响应,然后向用户授予对需要许可的资源的访问权限。

由于响应数据由 Google Play 签署,然后在服务器上进行检查,因此无法在运行应用的设备上修改该对象。如果应用依赖服务器,并且仅向合法用户提供资源,则应用将受到更大程度的保护,使其免受未经授权用户的侵害。

以下部分提供了执行服务器端许可验证时应牢记的其他注意事项。

防范重播攻击

用户收到来自 Google Play 的用户许可状态响应之后,可以复制响应数据并多次使用,或者将其提供给其他用户,然后其他用户就可以伪造对应用的私有服务器的请求。此类操作称为重播攻击

为了降低用户成功执行重播攻击的可能性,请在向应用服务器发送请求前采取以下措施:

  • 检查响应数据中包含的时间戳,确保 Google Play 是在最近生成的响应。

  • 对服务器请求执行速率限制,例如指数退避算法,以减少应用尝试向应用服务器发送相同响应数据的次数。

  • 在私有服务器上验证 Google Play 响应数据的内容之前,请先向私有服务器发出基于身份验证的初始请求。在第一个请求中,将用户凭据发送到服务器,然后让服务器以 Nonce 或仅使用一次的数字做出响应。然后,您可以在发送到私有服务器的下一个请求中添加此 Nonce,请求获取许可验证数据。如需详细了解如何为 Nonce 选择合适的值,请参阅生成合适的 Nonce 值部分。

生成合适的 Nonce 值

使用以下一种技巧创建一个很难猜到的 Nonce 值:

  • 根据用户 ID 生成哈希值。
  • 为每个用户生成一个随机值。将此随机值作为指定用户属性的一部分存储在应用服务器上。

验证来自服务器的响应数据

查看应用服务器向应用发送的响应数据时,请确保许可验证库的响应不是伪造的。将应用服务器响应数据中包含的签名与应用在上一步中从 Google Play 收到的密钥进行比较,以验证此签名。

还有一点值得注意的是,许可验证库 (LVL) 专用的块是唯一签名的部分。因此,在应用服务器的响应数据中,应用只应该信任这一个部分。