15

我已经在我的应用程序中实现了应用内计费 - 最近谷歌已经更新了它,之前我正在测试应用内计费"android.test.purchased"并且它工作正常(购买完整版并恢复完整版)。

现在我从这里获取更改的课程 https://code.google.com/p/marketbilling/source/detail?r=7bc191a004483a1034b758e1df0bda062088d840

之后我无法测试应用程序它在 Logcat 中给出以下错误"IabHelper: In-app billing error: Purchase signature verification FAILED for sku android.test.purchased ".

我检查了我的密钥、包名和应用程序版本都正确,有人遇到过这个问题吗?

请帮我解决一下这个。

4

2 回答 2

31

This is because of the verifyPurchase() method in the Security class that has been change in the new fixes. Let me show you what is the exact problem is:

Security class changes

OLD CODE

 public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
          if (signedData == null) {
            Log.e(TAG, "data is null");
            return false;
        }

        boolean verified = false;
        if (!TextUtils.isEmpty(signature)) {
            PublicKey key = Security.generatePublicKey(base64PublicKey);
            verified = Security.verify(key, signedData, signature);
            if (!verified) {
                Log.w(TAG, "signature does not match data.");
                return false;
            }
        }
        return true;
    }

New Code

public static boolean verifyPurchase(String base64PublicKey,
            String signedData, String signature) {

    if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
                || TextUtils.isEmpty(signature)) {
        Log.e(TAG, "Purchase verification failed: missing data.");
            return false;
    }

    PublicKey key = Security.generatePublicKey(base64PublicKey);
    return Security.verify(key, signedData, signature);

}

According to what I have searched and tested from New code,

Why it happens because we will not get any signature while we are using dummy product like "android.test.purchased". So in the old code it is working good because we were return true even if signature is not given and for the New code we are returning false.

more information about the signature data null or blank from link1 and link2

So I suggest you just replace old code method verifyPurchase() instead of New Code method.

I think may be New Code will work fine for the real product but not in the dummy product. But yet I have not tested for the real product.

Let me search more about this, why they changed code and what is the purpose behind that.

EDIT:

BuildConfig.DEBUG will also give you the solution for the test purchases.

In the verifyPurchase I changed return false to:

 Log.e(TAG, "Purchase verification failed: missing data.");
        if (BuildConfig.DEBUG) {
                return true;
        }
        return false;

but you should be aware to use this only in test scenario's.

This will return true, if you have a debug build, and the signature data is missing. Since the BuildConfig.DEBUG will be false in a production build this should be OK. But better is to remove this code after everything is debugged.

I have edited some code in the verifyPurchase() method, check it below:

public static boolean verifyPurchase(String base64PublicKey,
        String signedData, String signature) {

    if (signedData == null) {
        Log.e(TAG, "data is null");
        return false;
    }

    if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
            || TextUtils.isEmpty(signature)) {
        Log.e(TAG, "Purchase verification failed: missing data.");
        if (BuildConfig.DEBUG) {
            Log.d("DeBUG", ">>>"+BuildConfig.DEBUG);
            return true;
        }
        return false;
    }

    PublicKey key = Security.generatePublicKey(base64PublicKey);
    return Security.verify(key, signedData, signature);
}

I got this from GvS's answer android in app billing purchase verification failed.

hope it is helpful for you.

于 2013-10-23T10:31:01.580 回答
7

我是通知 Google 安全团队这些安全漏洞的人。请耐心等待,直到我公开披露这些错误,因为我给了 Google 时间来修复它们。如果没有大网站写过这个问题,我将在 11 月 6 日公开一个有效的漏洞利用。

正如您已经看过 verifyPurchase() 一样,该错误应该很明显。如果给定的签名是一个空字符串,该方法仍然返回 true(因为它默认返回 true)。

于 2013-10-24T16:42:10.023 回答