如何使用 Java (Servlet) 验证来自 In-App Billing Android Market 的签名数据

Posted

技术标签:

【中文标题】如何使用 Java (Servlet) 验证来自 In-App Billing Android Market 的签名数据【英文标题】:how can I verify signed data coming for In-App Billing Android Market using Java (Servlet) 【发布时间】:2011-12-21 05:03:44 【问题描述】:

在为 android 应用程序实现应用内计费时,我遇到了一个问题。

让我先解释一下场景 我们有一个包含产品列表的内容服务器(数据服务器)。 当用户从列表中选择一个时,他就可以购买它。 在我使用测试帐户输入信用卡详细信息后,购买逻辑运行完美。 作为回报,我在 Android 设备中获得了签名数据。

我的问题是 1.我是否必须验证Android设备中的签名数据,然后将一些信息或数据发送到内容服务器,内容服务器作为回报发送产品(我认为这可能不好,因为没有在服务器端流以验证请求是否有效或更准确地说;签名数据是否由谷歌市场生成)? 2. 如果我必须在服务器端验证数据,我该怎么做?我是否必须将其发送到 Google 市场(如果是,使用哪个网络服务或 API)?

请帮我纠正这个问题。 提前致谢。

【问题讨论】:

【参考方案1】:

对于第二个问题,对数据进行散列(例如:MD5、SHA)并将散列与数据一起发送到服务器。在服务器上,创建数据的哈希并比较哈希以验证它们。

【讨论】:

如何在服务器端制作哈希值并进行比较?请进一步探索。 @Naved 哈希算法是确定性的。如果你对相同的内容使用相同的哈希算法,无论数据在哪台机器上,你最终都应该得到相同的结果。 你能提供任何示例教程或分享一些示例程序吗?很抱歉,我无法完全理解。 @yogiam,谢谢你的提示。我的团队已经设置了一个服务器,它生成一个哈希字符串并将其发送到设备。该字符串与随机数(也在服务器端生成)一起用于在设备端启动事务。然后,设备将该哈希与签名数据一起发送到服务器,然后服务器验证请求。这工作正常,但我需要更多时间来进一步测试它。感谢您的支持。【参考方案2】:

要回答您的问题,您必须首先使用某种 ID 创建应用内产品,然后我会将其绑定到您服务器上的数据库中。然后使用 web 服务查询您的数据库并查看应用内 ID 是否与您的产品数据库中的 ID 匹配。另外,您可以使用安全Nonces 和签名进行验证。大多数情况下,您让 Google 处理产品,因此您将不得不在您的数据库之后为应用内产品建模。如果您有太多产品,那么您将不得不以创建移动网站的标准方式来处理它......

编辑: 好吧,当您提出请求(即购买)时,您首先执行 REQUEST_PURCHASE,然后启动市场返回的 PendingIntent。然后您处理由 Market 发送的广播意图。您在请求中指定四个键,然后发出购买请求:

  Bundle request = makeRequestBundle("REQUEST_PURCHASE");
  request.putString(ITEM_ID, mProductId);

  // Note that the developer payload is optional.
  if (mDeveloperPayload != null) 
      request.putString(DEVELOPER_PAYLOAD, mDeveloperPayload);
      Bundle response = mService.sendBillingRequest(request);
      // Do something with this response.
  

然后您必须使用 PendingIntent 来启动 checkoutUI(注意 1.6 到 2.0 的差异,其中 1.6 要求它与 Activity 分开启动)。查看 Google 示例中的 PurchaseObserver.java。

“Android Market应用发送一个RESPONSE_CODE广播intent,提供请求的错误信息。如果请求没有产生错误,则RESPONSE_CODE广播intent返回RESULT_OK,表示请求发送成功。(待定清楚,RESULT_OK 响应并不表示请求的购买成功;它表示请求已成功发送到 Android Market。)"

【讨论】:

这就是我们目前正在做的事情。但是,我的问题是,当我们从 Market 收到 nonces 和签名时,我是否必须将其发送到内容服务器?如果是,内容服务器如何知道签名和随机数不是手动生成的,而是由谷歌市场交易生成的? 感谢您花时间写这个答案。但是,我认为我的问题可能不清楚它的要求。好的,让我解释一下。我已经处理了设备端的所有事情。收到签名数据后,我必须将其发送到 Content Server。我的问题是内容服务器如何验证设备发送的签名数据实际上是交易而不是假交易。 您必须通过某种方式通过发送证书/密钥进行验证,然后您的程序会发回响应密钥。这确实是验证它不是虚假请求的唯一方法。 你的意思是你赞成 Yogiam 的说法?

以上是关于如何使用 Java (Servlet) 验证来自 In-App Billing Android Market 的签名数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 java Event.validateReceivedEvent 验证 webhook 始终无法通过签名验证

java使用servlet画出最简单的验证码一

Javaweb 响应——生成验证码

Javaweb 响应——生成验证码

Tomcat java servlet 在 Apple Pay 中验证商家

Web 应用程序如何推送通知(java/servlet)?