android - Google Play 结算响应签名验证

标签 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 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/

相关文章:

android - 无法使用 FaSTLane 将 Android APK 上传到 Google Play 商店

java - Android - 在圆圈中移动对象

android - Firebase crashlytics 错误 : Unable to load class 'org.gradle.api.tasks.TaskProvider'

java - 从 DER 格式的 String base64 编码创建 PrivateKey 和 PublicKey

java - delphi 解密转换Java代码

security - SSL 为 Web 应用程序做了什么

android - Flutter 文本按钮波纹效果

java - 照片删除后如何更新ArrayList <Bitmap>?

android - 应用程序与您的所有设备都不兼容

android - Google 提供的任何 Android Market API?