11

Is there a way to uniquely identify my Android App in Java code? Maybe some combination of the package name and something else? I know there is a way to identify a unique Android device, but that is not what I am looking for.

I want to be able to uniquely identify my Android app that I made so that I can then pass that information to my own private RESTful API. This would allow me to verify that the call is coming from my Android App and not another unauthorized one. I want my RESTful API to only work with the app I made and so no one can spoof it or access it unauthorized.

Or is this an impossibility? I'm just wondering how apps like Snapchat have their own login and what not. Clearly something there is securing it.

Community
  • 1
  • 1
Micro
  • 10,303
  • 14
  • 82
  • 120
  • 4
    "This would allow me to verify that the call is coming from my Android App and not another one" -- no, it will not, as anyone can pass the same information along to your REST Web service. For example, you could put the package name and a SHA256 hash of the public signing key in the URL to your REST Web service. Anyone else can find what those values are, just by examining the Web traffic, and put them in the same places in the URL to your REST Web service. – CommonsWare Aug 25 '15 at 15:24
  • @CommonsWare Even if you used https? – Micro Aug 25 '15 at 15:36
  • Generally speaking, yes. There are any numbers of proxies available for Android. Many can intercept HTTPS. Now, in theory, if you put in a lot of your own certificate validation logic, you might make it a bit difficult for somebody to successfully snoop on the HTTPS traffic. However, through reverse-engineering the app, they can either disable the certificate validation logic or just see how you are assembling the Web service calls. – CommonsWare Aug 25 '15 at 15:41
  • @CommonsWare So basically what you are saying is there is no way to secure your android app to your own restful api? Since the .apk can be decompiled, the most you can do is make the certificate validation logic very complex and hope no one is smart enough to decipher it? Then how does Snapchat or other other apps do it? – Micro Aug 25 '15 at 15:44
  • 1
    "So basically what you are saying is there is no way to secure your android app to your own restful api?" -- that depends entirely on your definition of "secure... to your own restful api". You seem worried about other apps using the API; that is not possible to completely prevent, for any client-side code (e.g., JavaScript in the Web browser). HTTP(S) requests are just bytes; any code can generate those bytes. Security by obscurity can make it difficult for attackers to determine how to generate those bytes, but it cannot stop such usage. – CommonsWare Aug 25 '15 at 15:50
  • @CommonsWare damn.. that really sucks. I wish there was a way. Didn't realize Android was so vulnerable. My rest api is going to be running credit cards via a custom payment gateway so if there is even a possibility of another app using those methods, I do not want to take the chance. https://wiki.usaepay.com/developer/javalibrary – Micro Aug 25 '15 at 16:04
  • Again, it is no more vulnerable than is in-browser JavaScript code in a Web app, hitting that same Web service. You might look at how somebody like Stripe handles their Web service API design. – CommonsWare Aug 25 '15 at 16:11
  • @CommonsWare Are there any other ways to build an android back-end then that are secure besides using restful api? Maybe I am missing something... – Micro Aug 25 '15 at 17:26
  • Unfortunately, once you lose possession of the hardware (ie it leaves your sight), then pretty much it's game over as far as secure communication goes between that device and your service. Obviously you can start designing your own custom hardware that self destructs any private key should it be tampered with but I think that's beyond the scope of this question. You can assume that 99.9% of your traffic is genuine, but you should make provisions for the traffic that is not (behaviour analysis etc). – Richard Green Sep 14 '15 at 09:59
  • It is possible, read this article http://android-developers.blogspot.com.au/2013/01/verifying-back-end-calls-from-android.html – CaptRisky Dec 28 '15 at 11:56

4 Answers4

4

If you want to use google maps from inside your app you need to supply an API key with every request. Google Maps Android Developer Site As far as I know that is the same mechanism that they also use to identify your app for advertisements. This key is transmitted in clear text so it can be intercepted. They do fraud detection to prevent misuse, so if your RESTful service is of the same kind as maps or ads this is the way to go for android apps.

If you have high value data like snapchat (nudes from people) the users have to provide a secret aka password to secure the connection. If you want to keep the effort for the user low you can use facebooks or googles authentication mechanisms.

Also take a look at Rest Security Cheat sheet it will give you a nice overview of the topic. (Especially the Authorization section.)

leonardkraemer
  • 6,573
  • 1
  • 31
  • 54
  • From what I read Snapchat had/has problems with third-party apps the reverse engineered their API and were able to make their own Snap-apps that users could login to and thus use the API. This is something I want to prevent. Providing a secret or password from the user is not enough, because I want to restrict other spoof Android apps from using my API. http://techcrunch.com/2015/04/03/why-your-favorite-snapchat-apps-no-longer-work/#.nmr9ge:cAwq – Micro Sep 16 '15 at 19:04
  • http://android-developers.blogspot.in/2011/03/identifying-app-installations.html thats what google thinks – leonardkraemer Sep 24 '15 at 16:59
2

This is a pretty broad topic area that's more related to the actual design of the RESTful service than Android. Generally speaking, RESTful services should be designed with the idea that anyone can access them, and you create security to ensure that your users data is kept private and only accessible by people who have the authority to access it as the reality of the internet is that once the endpoint is out there, people can and will try to access it.

Personally, I usually end up using JSON Web Tokens (JWT). You can include in a header a token that is validated by the server using credentials the user provides. This allows you to validate credentials and reject unauthorised access, as it is based on OAuth, as well as contain some additional ways to secure the service, including token expiry, so that the application has to renew the token every X minutes/hours/days etc., in case someone malicious does get a hold of the token. This also provides you a simple mechanism to identify the current user straight off the token. Here's a good introduction to JWTs and what they are composed of.

In summary, the nature of web services is that once they are exposed, any web connected device can theoretically connect through spoofing, packet inspection etc., and the only way to counteract it to block it to only your app connecting is to authenticate at a device level, which would require knowing every single device that is going to connect to the service. What I believe you need instead is strong authentication at the service level. A good REST API is platform agnostic, and used between apps and websites alike, with priority being on the security at a request level, rather than at a device level.

Andrew Breen
  • 685
  • 3
  • 11
  • Setting up a RESTful API the way you have described is correct. I was hoping though, there was some way with Android to really lock that API down. But even Snapchat has problems. Although they prohibit, they cannot prevent someone from making a third-party app from their private API. As a result, third-party apps have been made and Snapchat users just don't know any better and use them. I am looking for a way to prevent that with Android - but apparently it looks like that is not entirely possible http://blog.snapchat.com/post/99998266095/third-party-applications-and-the-snapchat-api – Micro Sep 16 '15 at 18:25
1

You may want to check one-time password mechanism. When your application installs, you authenticate your user and give a seed to your application. Whenever your application calls your Rest Service, you provide, along with service arguments, also a one-time password created from this seed.

One time password benefits.

The most important advantage that is addressed by OTPs is that, in contrast to static passwords, they are not vulnerable to replay attacks. This means that a potential intruder who manages to record an OTP that was already used to log into a service or to conduct a transaction will not be able to abuse it, since it will no longer be valid.

There exists an open standard HMAC-based One-time Password Algorithm with provided java code for you to start from.

Atilla Ozgur
  • 14,339
  • 3
  • 49
  • 69
  • Another way to call this mechanism is `2-step verification`? Am I right? – BNK Sep 12 '15 at 02:30
  • 1
    No. It is not the same. In 2-step verification you use same password always but use SMS in addition. Here your password always change but created from same seed therefore server and client creates same NEW password and verify it. – Atilla Ozgur Sep 12 '15 at 06:21
  • This still would not prevent from someone reverse engineering your android app, getting whatever API logic you have, and then spoofing your app. Snapchat has had a lot of problems with third-party apps doing just that. I am hoping for a unique way to identify just *my* android app but from these replies it looks like it may not be possible any other way. – Micro Sep 16 '15 at 23:00
  • @MicroR You did not read One time password algorithm clearly. Reading application logic and reverse engineering are useless since it is already an open standart. That is beauty of crypto algorithms, everybody supposed to know them. – Atilla Ozgur Sep 17 '15 at 00:27
  • @AtillaOzgur Maybe I am misunderstanding something but how would using one-time passwords prevent someone from spoofing your app then? – Micro Sep 17 '15 at 15:08
1

As others have mentioned, sending a static identifier is not going to ensure you are only picking up access from your app.

You need a way to create a handshake between your API and app, a simple but quite secure way of doing this is to have a key that both your app and your API share. When you make an initial connection to the API you create a random string, encrypt it using the shared key and pass the string and the encrypted string to the API, the API then encrypts your random string with it's shared key and compares it to your encrypted string.

For example:

Random String (RS) (generated by the app) = ABCDEFGHIJKLMNOP
Your shared key (SK) = AAAABBBBCCCCDDDD
Encrypt RS with SK to produce....
Your Encrypted string (ES) = WWWWXXXXYYYYZZZZ

send RS and ES to your API which then performs the same encryption using the same shared key. If the Encrypted strings do not match the API rejects the request and logs the RS so it cannot be used again If it does match, the RS is still logged, but access to the API is accepted. You can force re-authentication every time the app is used, you can also just send the RS with any further API requests as authentication has been completed successfully, but you must make sure that you time out the RS after a short time.

Mike Hall
  • 106
  • 6
  • If someone decompiled my Android App, couldn't they just view that shared key (sk) in the code? Then they just use whatever logic I have in my app to encrypted an RS, and make a call to the API with it, no? Or am I confusing something... – Micro Sep 16 '15 at 18:07
  • Yes, you would need to obfuscate your code, even then it's not bullet proof, but then, very little is. You could, for example, split your SK into numerous sub strings and use a function to recompile it correctly, use Proguard when you compile your app, etc. There is a good explanation of the use and benefits of Proguard on the Android developer site, http://developer.android.com/tools/help/proguard.html – Mike Hall Sep 17 '15 at 14:41
  • Yeah that is what I figured. One way or another, a determined hacker could work through the above logic. – Micro Sep 17 '15 at 14:51