Verifying in-app-purchases
Asked Answered
V

0

8

The sample app that the Google Developers guide refers to has a method called verifyValidSignature() that looks like this in the BillingManager class:

/**
 * Verifies that the purchase was signed correctly for this developer's public key.
 *
 * Note: It's strongly recommended to perform such check on your backend since hackers can
 * replace this method with "constant true" if they decompile/rebuild your app.
 */
private boolean verifyValidSignature(String signedData, String signature) {
    try {
        return Security.verifyPurchase(BASE_64_ENCODED_PUBLIC_KEY, signedData, signature);
    } catch (IOException e) {
        Log.e(TAG, "Got an exception trying to validate a purchase: " + e);
        return false;
    }
}

What exactly do they mean by "perform such check on your backend" ? What backend?

This method is called from this method (also in BillingManager):

private void handlePurchase(Purchase purchase) {
    if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
        Log.i(TAG, "Got a purchase: " + purchase + "; but signature is bad. Skipping...");
        return;
    }

    Log.d(TAG, "Got a verified purchase: " + purchase);

    mPurchases.add(purchase);
}

I don't really understand what I'm supposed to do on said backend, that is to stop an attacker from simply removing

if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
    Log.i(TAG, "Got a purchase: " + purchase + "; but signature is bad. Skipping...");
    return;
}

just as easily as replacing verifyValidSignature() with "constant true" as the JavaDoc for verifyValidSignature() warns.

How would I stop an attacker from decompiling my app and replacing something to bypass my in-app-purchase check?

Vagabondage answered 29/4, 2018 at 17:2 Comment(3)
That's the same thing that came to my mind... and we are not aloneComity
This is a very valid question. It obviously makes sense for someone who's going to reverse-engineer your stuff. But is there a scenario where there is a fraudulent purchase without anyone changing code? If so it seems like this would be a good protection against that at least. Although I am not even sure how this would work.Playpen
I found this while looking for an answer to this exact question. It seems that no matter what you do, you still have to have some way to send the data to your server from your application and some kind of listener listening for a response back from your server. So, after all the trouble of doing your back end verification, if the hacker can de-compile your listener and sender, they can make it send or return whatever they wanted. Did you ever figure out a way around this?Osmious

© 2022 - 2024 — McMap. All rights reserved.