【问题标题】:Android In-App Billing : Security.java says "Signature Verification Failed"Android 应用内计费:Security.java 说“签名验证失败”
【发布时间】:2011-10-27 14:05:30
【问题描述】:

我已经使用 Android 的应用内结算功能实现了一个测试应用。我已经在 Security.java 文件中填写了我的公钥。一切正常,但是当我提交付款时,应用程序崩溃了。我在 LogCat 中收到一条错误消息,上面写着“签名验证失败”,它对应于这段代码:

if (!sig.verify(Base64.decode(signature))) {
                Log.e(TAG, "Signature verification failed.");
                return false;
}

如果我将该位更改为返回 true 而不是返回 false,则一切正常 - 我可以提交付款并安全返回到应用程序 - 但我假设还有其他问题,因为我可能应该将其更改为返回真的。

关于什么可能导致这种情况的任何想法?

【问题讨论】:

    标签: android security signature verification in-app-billing


    【解决方案1】:

    签名验证错误可能由以下原因引起:

    1.- 公钥错误。也许你忘记了复制一些字符。它发生了:)

    2.- The .apk must be signed。您不能使用 debug.keystore,如果您这样做,您的签名字符串将为空。

    请记住,为了测试应用内结算:

    • 将 Android Market 公钥添加到 Security.java (String base64EncodedPublicKey = "your public key here")

    • 在发布模式下构建并签名(如果您使用的是 Eclipse,则可以使用导出向导)。

    • 将发布版本上传到Android Market,不要发布,创建产品列表。

    • 将应用程序安装到您的设备上 ( adb -d install myapp.apk ) 并在您的设备上设置一个测试帐户。

    【讨论】:

    • 您推送到测试设备的 APK 还必须与您上传到开发者控制台的 APK 具有完全相同的版本值。开发者控制台最多可能需要 6 小时来刷新您的 APK 版本。
    • 到今天为止,base64PublicKey 是传递给 IabHelper 的参数,它在 Security.java 中没有定义
    • 难道没有更简单的方法来开发计费集成流程而无需签名、上传、等待等操作吗?我同意应该在尽可能接近生产的地方进行测试,但是开发周期太长了。如果我错误地做了一个糟糕的 if 或 NPE,我需要重新完成整个发布阶段!
    • 我很惊讶谷歌仍然没有改进这一点。大量代码,非常复杂,很多事情都可能出错。这应该很容易集成。他们也不修复提交给源项目的未解决问题。
    【解决方案2】:

    就我而言,有一个隐藏得很好的问题。

    当我第一次设置应用内结算时,我尝试了静态响应并购买了 android.test.purchased 项目。当我切换到生产项目并试图查询库存时,那个假货给我带来了所有的麻烦。

    因此,在这种情况下,解决方案是从我拥有的物品中移除假冒产品。

    只需在 IABHelper.java 文件中添加这个 sn-p:

                    Purchase p = new Purchase(itemType, purchaseData, signature);
                    try {
                        consume(p);
                    } catch (IabException e) {
                        e.printStackTrace();
                    }
    

    在具有此签名的方法的 else 语句中:

    int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException
    

    清理完您自己的项目后,恢复到原始的帮助程序 java 文件。 当然,这只是开发阶段。

    【讨论】:

    • 像奇迹一样工作。应用内结算中的另一个错误。
    • 这个问题在当前的 Google 结算版本中仍然存在。基本上 android.test.purchased 坏了;购买 android.test.purchased 后,Security.java 中的 verifyPurchase 函数将始终失败,并且 QueryInventoryFinishedListener 将停止在 if (result.isFailure());这是因为 android.test.purchased 项目总是无法通过 Security.java 中的 TextUtils.isEmpty(signature) 检查,因为它不是真正的项目并且没有服务器返回的签名。
    • ... 并在查询时将您的应用内产品标记为“活动”
    • 您先生,是个奇迹创造者。多么明目张胆的神秘问题,早就该打补丁了!!
    • 这很好。谢谢
    【解决方案3】:

    在我的例子中,我粘贴了一个错误的具有相同前缀和后缀的公钥。只需确保 100% 正确即可。

    【讨论】:

    • 谢谢,你救了我!同样的问题 - 密钥非常相似,但对于不同的应用程序不同
    【解决方案4】:

    我的回答将来可能对某人有所帮助

    确保您的应用程序中有正确的 base64EncodedPublicKey

    【讨论】:

      【解决方案5】:

      如前所述,我使用了错误的 base64EncodedPublicKey。

      您可以在 Google Play 控制台中找到它,在您的应用标签下,转到 获利设置 标签,然后您可以复制它。

      【讨论】:

        猜你喜欢
        • 2013-01-14
        • 2013-01-04
        • 2012-01-18
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-06
        • 1970-01-01
        相关资源
        最近更新 更多