Android in app purchase: Signature verification fa

2020-01-25 03:49发布

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.

  • In the Dungeons demo, I passed my public key from the dev console.
  • Signed the apk and uploaded to console without publish.
  • Testing for both android.test.purchased & product list created on console with published for subscription (The main feature I want for my app).

But still I get an error of Signature verification failed and then the signature does not match data. How can I solve this?

public static ArrayList<VerifiedPurchase> verifyPurchase(String signedData, String signature)
{
    if (signedData == null) {
        Log.e(TAG, "data is null");
        return null;
    }
    if (Consts.DEBUG) {
        Log.i(TAG, "signedData: " + signedData);
    }
    boolean verified = false;
    if (!TextUtils.isEmpty(signature)) {

        String base64EncodedPublicKey = "MIIBIjA....AQAB";
        PublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
        verified = Security.verify(key, signedData, signature);
        if (!verified) {
            Log.w(TAG, "signature does not match data.");
            return null;
        }
    }
}

public static boolean verify(PublicKey publicKey, String signedData, String signature)
{
    if (Consts.DEBUG) {
        Log.i(TAG, "signature: " + signature);
    }
    Signature sig;
    try {
        sig = Signature.getInstance(SIGNATURE_ALGORITHM);
        sig.initVerify(publicKey);
        sig.update(signedData.getBytes());
        if (!sig.verify(Base64.decode(signature))) {
            Log.e(TAG, "Signature verification failed.");
            return false;
        }
        return true;
    } catch (NoSuchAlgorithmException e) {
        Log.e(TAG, "NoSuchAlgorithmException.");
    } catch (InvalidKeyException e) {
        Log.e(TAG, "Invalid key specification.");
    } catch (SignatureException e) {
        Log.e(TAG, "Signature exception.");
    } catch (Base64DecoderException e) {
        Log.e(TAG, "Base64 decoding failed.");
    }
    return false;
}

14条回答
成全新的幸福
2楼-- · 2020-01-25 04:45

Ran into the same issue (signature verification, and getting rid of the test purchase) today (Oct 30, 2018).

The signature issue is probably being caused by the fact that these test sku's are not really part of your app, and are thus do not have your app's signature. I did open a ticket with Google, but not sure if they can fix this. The workaround, as others pointed out, is to replace the code

if (verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {

with

if (verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature()) ||
                        (purchase.getSku().startsWith("android.test.")) ) { 

Regarding "how to get rid of the purchase of android.test.purchased SKU", I found that a simple reboot of the device, followed by waiting for a minute or so and/or re-starting your app a couple of times fixed it for me (i.e. I didn't have to 'consume' the purchase by code). I am guessing that the wait is needed so that the Play store completes syncing with Google's servers. (Not sure if this will continue to work this way in the future, but if it works for you now, this might help you move forward.)

查看更多
虎瘦雄心在
3楼-- · 2020-01-25 04:45

Check this answer:

Is the primary account on your test device the same as your Google Play developer account?

If not you won't get signatures on the android.test.* static responses unless the app has been published on Play before.

See the table at http://developer.android.com/guide/market/billing/billing_testing.html#static-responses-table for the full set of conditions.

And it's comment:

I don't think the static ids return signature anymore. See https://groups.google.com/d/topic/android-developers/PCbCJdOl480/discussion

Also, previously the sample code (used by many big apps) from Google Play Billing Library allowed an empty signature. That's why it's static purchases worked there.
But it was a security hole, so when it was published, Google submitted an update.

查看更多
登录 后发表回答