4

My server exposes number of REST services, I want secure the web services such a way that it can be consumed only by the android apps which is owned by me.

Essentially both client (android app) and server is developed by me; and I need to expose the REST service only to my android app.

I thought of number ways securing the REST service like

  • Using username/password based authentication
  • JWT token
  • Signature based verification
  • etc.

in all the cases android app should store the password in app; in that case hacker can easily decompile the app and get the password.

How can I secure my REST which can be accessed only by android app?

EDIT: Client app doesn't require any authentication from user

yottabrain
  • 2,387
  • 5
  • 23
  • 37

4 Answers4

3

You may use SSL with client authentication. The server has to know the public key of the app and the app has to know the public key of the server. App's private key is stored in the app itself using a keystore, which is a safe way to prevent decompilation, have a look to https://developer.android.com/training/articles/keystore.html

ALTERNATIVE:

Obtain hash of your app

public void traceKeyHash(Activity activity){
    try {
        PackageInfo info = activity.getPackageManager().getPackageInfo("your.package.here", PackageManager.GET_SIGNATURES);
        for (Signature signature : info.signatures) {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            Log.i(getClass().getName(), "Share - KeyHash: " + Base64.encodeToString(md.digest(), Base64.DEFAULT));
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

now you have to send your hash to your server, but ... to avoid sniffing of the request you have to encrypt your hash. Encrypt your hash with a private key stored in the keystore and use the public key at server side to decrypt the message, check if hash matchs the one you have registered.

jmhostalet
  • 4,399
  • 4
  • 38
  • 47
1

You can't. Authentication is done by sharing some secret between your client and your server. If you put that secret in your app, it will be decompiled and stolen (if anyone cares enough to). If you give that secret to a person (like a password), you can authenticate the person- but the person can type it into a fake app. When you're dealing with unknown hardware not under your control, there's no way to assure that its your app and not someone else's- you can only assure that the user is authorized.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
0

I suggest you never store password on client side. Use authorization keys. User enter login and password once on first authentication, then server check credentials and issue auth token. In result the client must store only token.

acelot
  • 752
  • 2
  • 7
  • 26
0
  1. make user to login to issue a token. save the app id for the token issuer.
  2. when accessing a web service with the token, server can verify that indeed this token is being issued to user x with appId y.
anurag gupta
  • 379
  • 1
  • 5