Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9207469
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T00:23:40+00:00 2026-06-18T00:23:40+00:00

Background: We have an Android app that is currently on sale via Google Play.

  • 0

Background:

We have an Android app that is currently on sale via Google Play. For the app to function the user must purchase a “token” via In-App Billing. The “token” is a consumable item, eg used once and finished with. To verify the token, we send the purchase data to a server which uses standard Java RSA security code to verify the information returned from the Play Store is valid. (Code below).
We did extensive testing prior to releasing the app, and even once the app is on the store, we did some more testing. The data being returned from Google passed verification every time. Then about the start of December the signature verification started failing. We haven’t changed the code or the app in the store, and the verification code on the server has remained static.

I’ve debugged the code, and ran the receipt data and signature data being returned from the Play Store and it indeed now fails verification. I’m at a loss to explain what has changed, or why the verification started failing, when it was working fine.

Question:

Has anyone come across this before, where signature verification failed in an app that hasn’t changed? Any tips on where to start looking to try and work out where the issues may be coming from?

Further Information

The only thing that I can think of changing, is Google released the in-app billing API v3, but that shouldn’t effect V2, which is what we use.

To aide development, we use the net.robotmedia.billing library to handle the IAB.

Below is the server verification code for data returned from Play Store

where encodePublicKey => our public key from Play Store

signedData => base64 encoded receiptData as return from Play Store purchase

signature => signature as returned from Play Store

public class Security {

    public final static Logger logger = Logger.getLogger(Security.class.getName());

    private static final String KEY_FACTORY_ALGORITHM = "RSA";
    private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";

    /**
     * Generates a PublicKey instance from a string containing the
     * Base64-encoded public key.
     * 
     * @param encodedPublicKey
     *            Base64-encoded public key
     * @throws IllegalArgumentException
     *             if encodedPublicKey is invalid
     */
    public static PublicKey generatePublicKey(String encodedPublicKey) {
        try {
            byte[] decodedKey = Base64.decode(encodedPublicKey);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
            return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
        }
        catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        catch (InvalidKeySpecException e) {
            logger.error("Invalid key specification.", e);
            throw new IllegalArgumentException(e);
        }
        catch (Base64DecoderException e) {
            logger.error("Base64 decoding failed.", e);
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Verifies that the signature from the server matches the computed
     * signature on the data. Returns true if the data is correctly signed.
     * 
     * @param publicKey
     *            public key associated with the developer account
     * @param signedData
     *            signed data from server
     * @param signature
     *            server signature
     * @return true if the data and signature match
     */
    public static boolean verify(PublicKey publicKey, String signedData, String signature) {
        Signature sig;
        try {
            sig = Signature.getInstance(SIGNATURE_ALGORITHM);
            sig.initVerify(publicKey);
            sig.update(signedData.getBytes());
            byte[] decodedSig = Base64.decode(signature);
            if (!sig.verify(decodedSig)) {
                logger.error("Signature verification failed.");
                return false;
            }
            return true;
        }
        catch (NoSuchAlgorithmException e) {
            logger.error("NoSuchAlgorithmException.");
        }
        catch (InvalidKeyException e) {
            logger.error("Invalid key specification.");
        }
        catch (SignatureException e) {
            logger.error("Signature exception.");
        }
        catch (Base64DecoderException e) {
            logger.error("Base64 decoding failed.");
        }
        return false;
    }

}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T00:23:41+00:00Added an answer on June 18, 2026 at 12:23 am

    Just an update. I never got to the bottom of why it stopped failing verification. We think it could be an issue with the Google Play servers and our Public Key.

    Anyway the solution, as far as it is, is to implement the In-App Billing v3 Api (which is magnitudes nicer than the old version BTW) and it starting working again.

    So, not really a definitive answer, but a fix as it were.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am currently developing an app for Android that uses the Google Maps API
I need to have ALWAYS a background service that will synchronize my Android application
We currently have an application that starts its own background services to manage syncing
I have an Android app with manage a countdowntimer (class CountDownTimer) that it is
I have an Android app, in which Activities fire long running operations that run
Background: I'm currently looking into building an Android VoIP app for work (we sell
I'm working on an Android app that uses uses a background worker thread. I
I have a problem that I want to create an Android App which captures
I have an iPhone app that does image manipulation via blending two UIImage objects
For my app, I have a fairly complex set of configuration options that user

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.