Android应用内结算:Security.java说"签名验证失败"

Chr*_*ris 14 security verification android signature in-app-billing

我已经使用Android的In-App Billing实现了一个测试应用.我在Security.java文件中填写了我的公钥.一切正常,但当我提交付款时,应用程序崩溃了.我在LogCat中收到一条错误,指出"签名验证失败",这对应于这段代码:

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

如果我将该位更改为true而不是返回false,那么一切正常 - 我可以提交付款并安全返回应用程序 - 但我假设其他错误,因为我可能应该更改它以返回true.

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

ger*_*lez 25

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

1.- 错误的公钥.也许你忘了复制一些角色.它发生:)

2.- .apk必须签名.你不能使用debug.keystore,如果你的签名字符串将是空的.

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

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

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

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

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

  • 令我惊讶的是谷歌还没有改善这一点.大量的代码,非常复杂,很多东西都可能出错.这应该是非常简单的集成.他们也没有修复提交给源项目的未决问题. (9认同)
  • 是否有更简单的方法来开发计费集成流程而无需签名,上传,等待等?我同意测试应尽可能接近生产,但开发周期太长.如果我错误地做了一个坏的if或NPE,我需要重新做整个发布阶段! (8认同)
  • 截至今天,base64PublicKey是传递给IabHelper的参数,它没有在Security.java中定义 (6认同)
  • 您推送到测试设备的APK还必须具有与您上传到开发者控制台的APK完全相同的版本值.Developer Console最多可能需要6个小时来刷新您的APK版本. (2认同)

Fra*_*llo 20

在我的情况下,有一个隐藏的问题.

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

因此,在这种情况下,解决方案是从我拥有的项目中删除假冒产品.

只需在IABHelper.java文件中添加以下代码段:

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

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

int queryPurchases(Inventory inv, String itemType) throws JSONException, RemoteException
Run Code Online (Sandbox Code Playgroud)

清理完自己的项目后,恢复原来的帮助程序java文件.当然,这仅适用于开发阶段.

  • 此问题仍在当前的Google结算版本中进行.基本上android.test.purchased被打破了; 购买android.test.purchased后,Security.java中的verifyPurchase函数将始终失败,QueryInventoryFinishedListener将停在if行(result.isFailure()); 这是因为android.test.purchased项始终未通过Security.java中的TextUtils.isEmpty(签名)检查,因为它不是真实项目,并且没有服务器返回的签名. (2认同)