Google Play 购买中签名验证失败

Posted

技术标签:

【中文标题】Google Play 购买中签名验证失败【英文标题】:Signature vertification failed in Google Play purchase 【发布时间】:2020-04-08 22:12:51 【问题描述】:

我有一个 php 后端,它与 Google Play 服务集成以验证从 APP 进行的购买。购买信息返回收据和签名,我需要验证购买是否正确。

我收到:

 
   ...rest of the data,
   receipt": 
      "orderId":"...",
      "packageName": ...,
      "productId":" ...,
      "purchaseTime": ...,
      "purchaseState": 0,
      "purchaseToken": ...,
      "autoRenewing": true
   ,
"signature": ...

我使用位于 Google Play 控制台中的公钥来验证签名。我通过添加 -----BEGIN PUBLIC KEY----- 和 -----END API KEY---- 手动将其格式化为 PEM。我还将这些行分成了 64 行,并且我还验证了公钥对应于正确的项目。

最后我使用phpseclib 库执行验证,但一直失败。

    $receipt= $transaction['receipt'];
    $rsa = new RSA();
    $rsa->loadKey(Yii::$app->params['public_key']);
    $verify = $rsa->verify(json_encode($receipt), $signature);

我对收据进行编码,因为验证方法需要一个字符串,但我不确定这一步。我是在测试环境中执行此操作的,因此购买不是真实的。我怀疑公钥不正确,但我是从开发工具 > 服务和 API > 许可和应用计费中得到的。有什么问题?

【问题讨论】:

我已经检查过 phpseclib 需要一个长度为 256 的签名,但 Google Play 返回的签名有 341 个字符。 我会说:发布您要验证的签名、明文并发布您用于验证的密钥。事实上,在我看来,(1)签名是 base64 编码的(即你需要通过base64_decode 运行它和(2)谷歌正在使用 PKCS1 填充,而 phpseclib 默认为签名的 PSS 填充. 您可以通过 $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); 将签名填充更改为 PKCS1 @neubert 看来你成功了,谢谢!如果您将其发布为答案,我可以接受。 【参考方案1】:

我会说:发布您要验证的签名、明文并发布您用于验证的密钥。实际上,在我看来,(1)签名很可能是 base64 编码的(即,您需要通过base64_decode 运行它,并且(2)Google 正在使用 PKCS1 填充,而 phpseclib 默认为签名的 PSS 填充. 您可以通过 $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1); 将签名填充更改为 PKCS1

【讨论】:

以上是关于Google Play 购买中签名验证失败的主要内容,如果未能解决你的问题,请参考以下文章

Android 应用内购买:签名验证失败

使用 JWT PHP 库导致“签名验证失败”的网站的 Google 登录

android in app billing 购买验证失败

Google Play 上新版本应用的上传失败并出现签名错误

Google Play结算库在购买交易失败或取消时不会发出orderId,但它会在控制台中显示

Google Play In-app billing 版本 3 购买的服务器端验证