Android in app purchase: Signature verification failed

后端 未结 14 692
说谎
说谎 2020-11-28 02:27

I have tried for several days to solve this problem, using the Dungeons demo code that comes with the SDK. I\'ve tried to Google for an answer but can\'t find one.

相关标签:
14条回答
  • 2020-11-28 03:21

    Based on GMTDev's answer, this is what I do in order to fix the testing issues when consuming products in the simplest possible way. In Security.java, replace the verifyPurchase() method with this:

    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 BuildConfig.DEBUG; // Line modified by Cristian. Original line was: return false;
        }
    
        PublicKey key = Security.generatePublicKey(base64PublicKey);
        return Security.verify(key, signedData, signature);
    }
    

    I only modified one line (see comment), and this way you can keep the code like that for debugging and still publish your release versions safely.

    0 讨论(0)
  • 2020-11-28 03:23

    This problem is still going on in the current Google billing version. Basically the android.test.purchased is broken; After you buy android.test.purchased the verifyPurchase function in Security.java will always fail and the QueryInventoryFinishedListener will stop at the line if (result.isFailure()); this is because the android.test.purchased item always fails the TextUtils.isEmpty(signature) check in Security.java as it is not a real item and has no signature returned by the server.

    My advice (from lack of any other solution) is to NEVER use "android.test.purchased". There are various code tweaks on the net but none of them work 100%.

    If you have used the android.test.purchased then one way to get rid of the error is to do the following:-

    1. Edit Security.java and change the "return false" line in the verifyPurchase to "return true" - this is temporary, we'll be putting it back in a minute.
    2. In your QueryInventoryFinishedListener, after the "if (result.isFailure()) {...}" lines add the following to consume and get rid of your never ending android.test.purchased item:

      if (inventory.hasPurchase(SKU_ANDROID_TEST_PURCHASE_GOOD)) {  
         mHelper.consumeAsync(inventory.getPurchase(SKU_ANDROID_TEST_PURCHASE_GOOD),null);
         }
      
    3. Run your app so the consunmeAsync happens, this gets rid of the "android.test.purchased" item on the server.

    4. Remove the consumeAsync code (or comment it out).
    5. Back in the Security.java, change the "return true" back to "return false".

    Your QueryInventoryFinishedListener will no longer error on the verify, everything is back to "normal" (if you can call it that). Remember - don't bother using android.test.purchased again as it will just cause this error again... it's broke! The only real way to test your purchasing it to upload an APK, wait for it to appear, and then test it (the same APK) on your device with logging enabled.

    0 讨论(0)
提交回复
热议问题