我正在开发一个使用应用内购买的 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 signs the JSON string that contains the response data for a purchase order. Google Play uses the private key that is associated with your application in the Developer Console to create this signature.
我不太擅长加密,但我的理解是 RSA 签名的工作原理是采用要签名的字符串的 SHA1 哈希值,然后使用私钥对其进行加密以生成签名。当想要验证字符串的来源时,使用公钥解密签名(证明它是用私钥加密的),并将解密的散列值与消息的散列值进行比较,看它们是否匹配。
但是,这里有一个问题。签名本身包含在发送到我的应用程序的 JSON 字符串中。签名后您无法更改字符串,因此当 Google 说他们“签署包含响应数据的 JSON 字符串”时,他们并不是指我收到的整个 JSON 字符串。他们必须签署字符串的某些部分并将签名附加到该部分。我的问题是我无法弄清楚字符串的哪一部分被签名了。使用this question 中描述的签名验证实现。我尝试验证删除了签名属性的 JSON 字符串,没有括号,只有收据部分等。为了好的措施,我尝试了整个字符串,包括签名。我似乎找不到此 JSON 字符串的任何部分,可以使用我的公钥进行密码验证。是否有我应该使用的字符串的某些部分,或者我只是不明白签名是如何工作的?
最佳答案
对于任何使用 java 通过公钥验证 google pay 签名的人,请注意:
签名数据是一个 json 字符串 ONLY ONLY ONLY 包含 orderId
, packageName
, productId
, purchaseTime
, purchaseState
, purchaseToken
.
例如: 如果来自 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"
}
希望这篇文章对有需要的人有所帮助。
关于android - Google Play 结算响应签名验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31349710/