0

I have android app that connects to my backend server to fetch data. Right now, it serves as an open API.

Some one can modify my app, and still be able to connect to my backend server and get data. How can I SECURELY prevent it?

So in other words, I want that ONLY APKs that are signed by me be able to get service from my backend server. How this can be implemented?

Solution should not rely on signing in users. Users do not need to be registered to get service from the server.

[edit] Bonus Question: I publish source code of my app in GIT. So I do not have much options in hiding some keys inside the source code. Yet I want only the apps signed by me to be able to connect to my server. Is it possible?

cybergeek654
  • 290
  • 1
  • 5
  • 15

3 Answers3

1
  1. Get certificate fingerprint from your app. follow this link. This fingerprint is generated from code so it can't be stolen by decompiling apk.
  2. You can send this fingerprint using POST API as POST data is encrypted.
  3. Verify this SHA on your server, if that matches then request is coming from your app.
Community
  • 1
  • 1
Nikhil
  • 3,711
  • 8
  • 32
  • 43
1

You can validate your certificate signature/private key (contained in a .keystore or .jks file) at your server for API call you want to secure.

1) embedded your app's signature in your API .

2) send signature as a parameter with API call from your app.

3) Check that the signature at runtime matches to your embedded developer signature and respond your request accordingly.

You can get signature runtime with:

public static String checkAppSignature(Context context) {
    try {
        PackageInfo packageInfo = context.getPackageManager()
                .getPackageInfo(context.getPackageName(),
                        PackageManager.GET_SIGNATURES);
        for (Signature signature : packageInfo.signatures) {
            byte[] signatureBytes = signature.toByteArray();
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(signatureBytes);
            final String currentSignature = Base64.encodeToString(md.digest(), Base64.DEFAULT);
            //signature at runtime
            return currentSignature;
        }
    } catch (Exception e) {
        //something went wrong, let caller decide on what to do.
    }
    return "INVALID_SIGNATURE";
}
Gopal
  • 1,734
  • 1
  • 14
  • 34
0

Differentiate your application access by unique customer-ID or Device-ID. Whenever your application is making requests verify those ID's on your server side.

  • isn't it possible to get these Id by decompiling apk? – Nikhil Sep 02 '16 at 10:27
  • It would require that I keep a list of registered (trusted) customer-IDs or device-IDs, right? But I dont want to make my users to sign up. Anyone who gets a copy of my original app should be able to connect to my webserver, as long as the apk is not tampered. – cybergeek654 Sep 02 '16 at 10:29
  • 1
    I am not telling user to sign up.You generate a unique ID in the app using various combinations.On the next level you can encrypt those IDs with BASE64 or SHA algorithm and enabling the proguard in your app will obfuscate the code so it is not understandable. – Pankaj Jadhav Sep 02 '16 at 10:30
  • I see. so it is an arbitrary algorithm for creating some codes. I will then check if the code I receive is a valid code, right? – cybergeek654 Sep 02 '16 at 10:42
  • Yes if you don't want this you can generate unique APP IDs too. – Pankaj Jadhav Sep 02 '16 at 10:46