11

I've finished developing my app that uses in app billing v3. My app is an exam help app which has a list of questions which are inserted into a database. The thing that worries me is security as beyond proguard there is pretty much little else. My app queries the inventory for purchased items so storing purchases isn't a problem.

So the first issue is someone could decompile the app (which I've done) and even with proguard you can without too much difficulty retrieve all the questions.

The next thing is the application's public key. This can easily be taken from my app and according to the developers guide, this is something I should keep secure.

However I really don't know how to implement any form of security. Or even how far I should go with security. Without a server, if I'm keeping everything on the device I recognise it won't be perfect (far from it) but I would at least like hackers to be deterred rather than amused.

So essentially the question is:

What type of security should I use and how is it used? Just pointing me to links that go through it step by step so I can understand it would be amazing.

Thank you very much!

Clarification:

There is no server involved. The data is stored in the app. When it the inventory is queried (through the queryinventoryasync method) it returns back if an inventory is bought or not and this runs every time the app launches. In app billing itself I presume is okay, I'm asking more about my own application the application public key - I'm meant to somehow make that harder to copy but currently I have just broken it into 15 strings and I just "add" them to each other on runtime but that's barely any better then just having it as one string. I'd like to encrypt it somehow just don't know how.

AndroidPenguin
  • 3,435
  • 2
  • 18
  • 40

1 Answers1

18

Good question.

Public key must be available on device in order to be used. Once it comes on device it's not really protected anymore. The key itself is not a secret, but we need to make its possible replacement to be a more difficult task.

What you can do is to use so called XOR encryption. Here is an example if XOR encrypter and decrypter methods.

public static String xorEncrypt(String input, String key) {
    byte[] inputBytes = input.getBytes();
    int inputSize = inputBytes.length;

    byte[] keyBytes = key.getBytes();
    int keySize = keyBytes.length - 1;

    byte[] outBytes = new byte[inputSize];
    for (int i=0; i<inputSize; i++) {
        outBytes[i] = (byte) (inputBytes[i] ^ keyBytes[i % keySize]);
    }

    return new String(Base64.encode(outBytes, Base64.DEFAULT));
}

public static String xorDecrypt(String input, String key) {
    byte[] inputBytes = Base64.decode(input, Base64.DEFAULT);
    int inputSize = inputBytes.length;

    byte[] keyBytes = key.getBytes();
    int keySize = keyBytes.length - 1;

    byte[] outBytes = new byte[inputSize];
    for (int i=0; i<inputSize; i++) {
        outBytes[i] = (byte) (inputBytes[i] ^ keyBytes[i % keySize]);
    }

    return new String(outBytes);
}

How what you need is to choose a password string (String key) and encrypt your public key (String input) using it. This encrypted key you can store in a class. When you need your real key value, you call xorDecrypt() with the password and public (encrypted) key string. Password is a string you store somewhere in your code too. As I said we do not really protect it, but we make it more difficult to find and/or replace.

You can add more sophisticated logic on how to combine encrypted public key and password too. This just add more complexity but won't give you any warranty your key wont be decrypted. In any case Google confirms XOR encryption is better than nothing.

Android 4.3 added some more security features which can be used for storing public keys too. This solution will require a server communication and hardware support to be really safe. These are Key Chain enhancements and Android Keystore Provider.

sergej shafarenka
  • 19,464
  • 6
  • 62
  • 82
  • Awesome answer. Additionally should I break up my encrypted public key into various parts which I combine together reversing strings and shuffling characters about? What I understand is the idea is to stop someone replacing their key with yours thereby diverting money gained from purchasing items to their account. – AndroidPenguin Aug 22 '13 at 14:50
  • 1
    Thanks! a) Yes, you can break your encrypted public key in parts too. This will make hacker's life more difficult ... or maybe more interesting for them. b) Not really. The idea is to make it more difficult to replace your public key with a fake one. Then re-assemble your app, that it starts to accept fake server responses. Thus hackers can enable function without paying for them. – sergej shafarenka Aug 22 '13 at 14:58
  • ' int keySize = keyBytes.length - 1;' this is not nessesary. i % keySize always less than keySize so we dont have to minus keySize for 1 – Nhat Dinh May 28 '15 at 07:32