Google Play结算回复签名验证

时间:2015-07-10 20:25:31

标签: android encryption google-play rsa sign

我正在开发一款使用应用内购买的Android应用。用户进行购买后,Play商店将响应作为JSON字符串发送。该响应看起来像这样(当然没有编辑敏感信息):

{  
   "type":"android-playstore",
   "id":"<My Application ID>",
   "purchaseToken":"<The Purchase Token>",
   "receipt":{  
      "orderId":"<The Order ID>",
      "packageName":"com.example.skeleton",
      "productId":"credit.basic",
      "purchaseTime":1436546971245,
      "purchaseState":0,
      "purchaseToken":"<The Purchase Token>"
   },
   "signature":"Im27prAnxYwdRoug..."
}

Google Play billing security documentation表示

  

Google Play会签署包含采购订单响应数据的JSON字符串。 Google Play使用与开发者控制台中的应用程序关联的私钥来创建此签名。

我对加密不是很好,但我的理解是RSA签名的工作原理是将字符串的SHA1哈希值签名,然后使用私钥加密以产生签名。当想要验证字符串的来源时,使用公钥解密签名(证明它是使用私钥加密的),并将解密的散列与消息的散列进行比较,以查看它们是否匹配。

然而,这里有一个问题。签名本身包含在发送到我的应用程序的JSON字符串中。您无法在签名后更改字符串,因此当Google表示他们“签署包含响应数据的JSON字符串”时,他们并不意味着我收到的整个JSON字符串。他们必须签署字符串的某些部分并将签名附加到该字符串。我的问题是我无法弄清楚该字符串的哪个部分已签名。使用this question中描述的签名验证实现我尝试删除了删除了签名属性的JSON字符串,括号,只有收据部分等。为了好的措施,我尝试了整个字符串,包括签名。我似乎无法找到可以使用我的公钥进行加密验证的此JSON字符串的任何部分。是否有我应该使用的字符串的一部分,或者我只是不明白签名是如何工作的?

2 个答案:

答案 0 :(得分:2)

对于使用java通过公钥验证Google付费签名的任何人, DO 会注意: 签名数据是json字符串 包含orderIdpackageNameproductIdpurchaseTimepurchaseStatepurchaseToken

例如: 如果来自Google Pay的响应数据如下所示:

{
    "nameValuePairs": {
        "orderId": "your.order.id",
        "packageName": "your.package.name",
        "productId": "your.product.id",
        "purchaseTime": 1526476218113,
        "purchaseState": 0,
        "purchaseToken": "your.purchase.token"
    }
}

然后,您将检查签名的签名数据是,如下所示:

{
    "orderId": "your.order.id",
    "packageName": "your.package.name",
    "productId": "your.product.id",
    "purchaseTime": 1526476218113,
    "purchaseState": 0,
    "purchaseToken": "your.purchase.token"
}

希望这篇文章对任何需要它的人都有所帮助。

答案 1 :(得分:0)

正如经常发生的那样,在StackOverflow上发布的30分钟内,我发现了它。

问题源于我在PhoneGap中开发此应用程序并使用in-app-purchasing plugin执行此事务的事实。当它给我上面的JSON字符串时,该插件对我有点说谎。 Google将响应数据发送到一个JSON字符串,将签名发送到另一个JSON字符串,而插件将其包装到上面的单个字符串中。正确的方法是验证收据&#39;项目,如下所示。

{  
      "orderId":"<The Order ID>",
      "packageName":"com.example.skeleton",
      "productId":"credit.basic",
      "purchaseTime":1436546971245,
      "purchaseState":0,
      "purchaseToken":"<The Purchase Token>"
 }

问题中列出的python实现验证了此JSON字符串的签名。