Information Security Stack Exchange is a question and answer site for information security professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to know how I can achieve strong encryption of a public key present in my Android application.

It's Android's advice that

To keep your public key safe from malicious users and hackers, do not embed your public key as an entire literal string. Instead, construct the string at runtime from pieces or use bit manipulation (for example, XOR with some other string) to hide the actual key. The key itself is not secret information, but you do not want to make it easy for a hacker or malicious user to replace the public key with another key.

There are certain solutions given like having substrings and encryption, but I want to know how can I achieve it in an efficient manner.

share|improve this question
For what? For worthless snake-oil "copy protection" in which scenario the user is your potential opponent? Or for a secure protocol in which you are on the user's side? – thejh Apr 3 '13 at 18:20
up vote 11 down vote accepted

First, note that what you need is not encryption. This advice is about public keys. Public keys are, as the name indicate, not secret (except sometimes for privacy — but when your application's key is in your application, there's no privacy involved). What you need is to ensure the integrity of the public key, i.e. ensure that a malicious entity cannot replace it by a different key.

The application uses the public key to authenticate a purchase order. The normal sequence of events for a purchase is:

  1. The user contacts a Google server and pays some money to purchase an in-app feature.
  2. The Google server issues a receipt for that purchase. It signs this receipt with a private key that never leaves the server.
  3. Your application running on the mobile device downloads the receipt.
  4. Your application verifies that the receipt is genuine, relying on the public key bundled with the application.
  5. If the purchase is a repeatable one (e.g. allowing to download X minutes of protected content, as opposed to unlocking a feature), the application must ensure that the same receipt cannot be used twice (replay attack). It does so by “consuming” the purchase.

The problem is that the user may modify the code or data of your application to put a public key of his choosing instead of the genuine one. In particular, he may put a public key for which he knows the private key. If he does this, he can generate purchase receipts without going through any server, and your application will accept them as genuine at step 4.

What you need to do to protect against this attack is to detect any attempt at modifying the public key. It doesn't matter if the potential attacker can read the public key, as long as he cannot change it. This means your application should contain code that verifies that the key is genuine. But whatever you do, the attacker could change the verification code (just flip a bit somewhere to change if is_genuine(public)key) to if not(is_genuine(key)))...

So you need to make it impossible for the attacker to find the verification code. Not only that: you must make it impossible for him to jump over the verification code and into the interesting part. You need to obfuscate your whole application. But obfuscation is hard if not impossible.

There are only two ways you can benefit from obfuscation:

  • If no one cares about your app, maybe no one will try to crack it. (Downside: you aren't making any money either.)
  • You put a lot of effort into it, and only hope for it to hold for a small amount of time. Note that significant effort must be put into each release: if a lot of software is released with the same obfuscation techniques, someone will find a way to crack it, and all that software will be exposed.

For a success story of obfuscation, I recommend reading Gavin Dodd's story about the game Spyro: YOTD. The key points are that it took a lot of effort, that the objective was only to delay the crack for a couple of months, and that it relied in part on the psychology of the attackers who only spend limited time attacking each game and stop as soon as they've passed the first hurdle.

In most cases, obfuscation will cost you far more than it can benefit you.

So what can you do? As advised in the article: don't verify the purchase on the device, verify it on a server under your control. This is only useful if the result of the purchase comes from a server. For example, if the purchase is for additional content or features, the receipt should unlock the content in the user's account on the server, and the app would download any content that the server lets it have.

share|improve this answer
Do you know any library or sample code for server side verification, that works with v3 API? – Mr.Hyde Feb 7 '15 at 7:38

Whatever encryption you use, it's still on the client's device, so they can decrypt it. You're running into the same problem as DRM systems have, whereby anything you hand over to the user can be modified.

If the security of your application depends on the secrecy of your public key, then you have a fundamental flaw in your architecture, and need to attack the problem from a different angle.

If you're just trying to prevent users from changing the public key so that they can use custom private servers, then the most you can do is obfuscate it and hope for the best.

share|improve this answer

@Polynomial has pretty much nailed it as usual, but for some expansion on what he means by obfuscate;

As the android documentation suggests, you want to make the public key a little difficult to pull out from the binary. You essentially have two layers of protection;

  1. Build the key at run-time using some reasonably complex approach. XOR is good, some kind of iteration is good, transposition and substitution are good too.
  2. Obfuscate your key derivation mechanism. By this I mean employ anti-debugging techniques to your code. Few developers go to this extent, but it all helps.
share|improve this answer
Could i get a sample of doing all the aforementioned steps ? I would also like to implement check sum like MD5. – Adithya Apr 4 '13 at 7:23
The relative success of (1) partly depends on how you implement it right? For instance, you may have a super complex way of assembling a key, but if you assemble it into a variable and pass it into's constructor, then an attacker could just replace that variable's value right? I'm thinking that the building of key at run time has to be done only when it is required.. – kevinze Mar 12 at 16:06

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.