2

I need to protect the server API against usage from any client excepting the app I'm creating.

There are no "users", so I thought I can use SSL with hardcoded login / pass.

After quick investigation I figured out that hardcoding even encrypted login & pass into the app is a bad idea - there is always a way for intruders to analyze the decompiled code and find actual login and pass even from encrypted storage.

Then I started digging in the direction of the authentication with Certificates. It turned out that nowadays standard SSL authentication with certs is not secure, and it's better to use SSL Pinning technique.

SSL Pinning implies attaching a copy of the server's cert to the app bundle, to secure the cert verification step.

But I cannot understand whether the SSL Pinning could be implemented in a reverse way, that is to store the client's cert on the server and perform the cert check on the server side to make sure the connecting client is my app. It looks like the cert attached to the app also could be extracted and used externally to authenticate other clients.

nalexn
  • 10,615
  • 6
  • 44
  • 48

3 Answers3

3

In order to prevent 3rd parties from accessing your service, you need to tell your own client app and the 3rd parties apart.

It does not matter what kind of differentiation - an app-id, a secret, a certificate (which is just a form of secret in such case) - you build into your client app, it must still be inside of it and there is no reliable way to prevent reverse engineering it. It is just a matter of motivation / resources.

If TLS is used to communicate to the services, you could embed some random secret into the application code. In case of no TLS, you should better embed an encryption key (symmetric or asymetric) and encrypt or sign your data so your secret is at least not revealed plain-text in the communication channel.

Vilmantas Baranauskas
  • 6,596
  • 3
  • 38
  • 50
  • Thank you for the answer. Since there is no way to protect the app from reverse engineering, I'll need to make the task for intruders as hard as possible. Password stored as a plain text or a cert added to the bundle are too easy to be obtained from the app. How would you recommend to store / calculate the secret so that it would be hard to get form the app? – nalexn Dec 22 '14 at 18:18
  • 1
    Could it be that you overestimate the motivation of others to access your services? If it is really that important, maybe you have got your security concept wrong? If there is really no other options, be prepared to play a cat-mouse game: Alter your protection now and then so 3rd party Apps get broken without a notice. – Vilmantas Baranauskas Dec 23 '14 at 07:16
  • The service I'm working on does not really require severe security - It's just my own wish to get to how to do the protection right. – nalexn Dec 23 '14 at 15:53
1

If you want a high level of security, then what you're asking isn't possible. That is, if the only "authentication" you have is someone who downloads a free app, then you really don't have any "authentication" at all.

The entire HTTP(s) conversation between your app and the server can be viewed and re-played fairly easily. Therefore, any encrypted credentials you place on the app could be reverse engineered.

You've mentioned some simple - but completely insecure tricks - which would thwart non-malicious users and make reverse engineering more difficult. These include storing a password or cert in a not-so-obvious location, combined with SSL. Sometimes this is good enough - but it sounds like you've ruled those out.

If you look at conventional licensed software you run on your PC, such as Microsoft Office, they always have some license key or additional piece of information the user enters. Perhaps you can offer "license keys" of your own for this app?

If you really want to safeguard your app from malicious clients, you'll need users or some external key.

If you do have users, your best bet is to store only a session token with your app. (Typically Shared Preferences are used.) Use an offsite Oauth API such as Facebook, Twitter (or your own service) to perform authentication and get your token. An Oauth service typically has a identifier for each app. For example, Facebook uses a "App ID" which can be used to disambiguate between apps and validate the token. On the API or service side, you will need to validate the token with Facebook's API. This requires an extra API call from the service.

Charlie Dalsass
  • 1,986
  • 18
  • 23
0

Because there are no "users" you cannot tell apart normal users and malicious users.

You can, however, do some basic DRM for your application to prevent extracting the credentials. Both iOS and Android have secure partitions on their file system where you can store credentials which are more difficult to extract via reverse engineering. However, this protection is not 100%, but might slow down the potential attacker a bit. This is usually what mobile games are doing.

How to store secrets within your mobile application is subject to another question, depending on the used platform, system version number on so on.

E.g. https://stackoverflow.com/a/786588/315168

Community
  • 1
  • 1
Mikko Ohtamaa
  • 82,057
  • 50
  • 264
  • 435