17

I retrieve data from an external server for use with my android application. I would like this data to be only accessible with my app. I use a standard http connection to get the data from apache/php server in json format. I also send some params to the server to retrieve relevant data. Now, what I'm planning to do is:

  1. Send the params
  2. Send something like md5("someSecretPhrase"+params).
  3. Check if the secret phrase is correct on the server side.

Now, the question is - is it a safe approach regarding the reverse engineering? For now I can think of no other possibility to get this data. But if someone is able to decompile my apk, he will be also able to retrieve this "someSecretPhrase" (rather hard to do on the server side) and then access the server, isn't he? Is it a real threat? Is there any other possibility to authenticate my app by the server?

I looked at the forums eg. Identify whether HTTP requests from Android App or not? and then respond appropriately, but they don't explain the decompilation problem.

Community
  • 1
  • 1
Michał Klimczak
  • 12,674
  • 8
  • 66
  • 99

5 Answers5

10

One of basic rules of security is: you don't trust client data. Ever.

You should consider your app decompiled, all "secret" keys known to attacker, etc.

You can, however, hinder attacker's attempts to forge your requests. Sending (and verifying) checksum of your request is one of methods (your idea of MD5(secret_key + params)).

You could also switch to a binary encrypted protocol. But this requires MUCH more work and quite a different architecture of server.

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • I'm starting on a shared hosting, so different architecture on the server is probably not an option for me. This data is not that vulnerable (no client credit card numbers), but it will require lots of work to gather it (and it will be gathered continuously) so it would be really bad if someone could just copy my idea and use the data... – Michał Klimczak Dec 28 '11 at 00:57
  • 2
    Well, if your server replies with some data, you should consider it public. Besides decompiling your app and faking requests, he (attacker) could simply use a proxy and dump data you send to your legitimate app. – Sergio Tulentsev Dec 28 '11 at 00:58
  • So, if I understood you correctly, the only option to do it safely is to use an encrypted connection between server and the app. Https would be ok? I understand, that it's not that easy to use. But what are other drawbacks? It's considerably slower, isn't it? I'm just trying to find out if the safety of this data is worth the effort – Michał Klimczak Dec 28 '11 at 01:08
  • @MichałK: in my practice, I have found that in most (well, all) cases a simple checksum is enough. But then again, I didn't do bank clients and all that stuff. – Sergio Tulentsev Dec 28 '11 at 01:21
  • And it's not the case here, so I'll probably stick to checksum too. Thank you! – Michał Klimczak Dec 28 '11 at 19:10
4

You can hide your links by set all url links and paramete names in strings.xml for example: http://wwww.yourdomain.com/yourpage.any user_name and get url such at :

String serverUrl = Resources.getsystem().getstring(R.strings.name_your_link_id); String parameterKey = Resources.getsystem().getstring(R.strings.name_your_parameter_id); Uri url = Uri.parse(serverUrl+"?"+parameterKey+"=" + yorusername);

and make any http request HttpURLConnection con = (HttpURLConnection) url.openConnection();

when any one try to decompiled your app he will show only id as long integer in R.java file get code such this String serverUrl = Resources.getsystem().getstring(12346546564); String parameterKey = Resources.getsystem().getstring(123321321132);

  • 5
    But I think it would only make it a little bit more cumbersome, not impossible to get. The string resources are inside resources.arsc when you unpack an *.apk file. So they are still associated with those numbers. But +1 for an interesting idea – Michał Klimczak Sep 25 '14 at 18:50
4

Android requires that one should sign their app(signing authority or self signed) before it can be installed. We can utilize this to check whether requests are coming from your app or not.

  1. Sign your app with your certificate.
  2. Find the certificates signature and save it in your backend server.
  3. For every request, expect this signature to be sent by the app.
  4. validate the signature sent by the app at server level and accept only if they matches.

Even in that case where someone tampers with your app, he has to sign it again before it can be installed, which would change the apps signature and our validation mechanism would simple reject all such requests.

This answer is based on this blog. Use https for app<->server communication.

varun
  • 341
  • 2
  • 17
  • 8
    But any one can use the signature code to find your app hash using your app package name and can start sending that hash in future request. Then how this signature is making the app secure? – varun bhardwaj Sep 27 '16 at 05:56
  • 3
    How to do step 3, is it default behavior of Android OS? – Jacob Dam Nov 22 '16 at 11:00
2

Have your application perform a handshake with the server, so the algorithm isn't just a string, but a whole process. Use Sessions/databases to track your handshake

Adam Fowler
  • 1,750
  • 1
  • 17
  • 18
  • 1
    And a handshake is performed over ssl, isn't it? So it would be pretty much the same thing as we mentioned in comments eralier (don't mean checksum here). But it's good to know that this thing is called handshake, thanks! – Michał Klimczak Dec 28 '11 at 19:07
1

Unfortunately if someone decompiles your apk, then it can easily see your strings.

EDIT: I don't think there is a better way to do this.. maybe only to publish your application on android market with the android Copy Protection turned On...

Cata
  • 11,133
  • 11
  • 65
  • 86
  • Thank you for your prompt answer. Decompilation is a pretty simple process, I suppose? I mean, I shouldn't rely on the assumption that it won't be decompiled? Hmm, there HAS to be some other solution... – Michał Klimczak Dec 28 '11 at 00:52
  • 1
    You can authenticate users, you can't authenticate applications, you can make it harder, but at the end of the day you're shipping the code & secrets to the bad guys. – superfell Dec 28 '11 at 01:44
  • Yeah, I'll probably get over it or invest in some encryption when the data proves its value. That said, I'm pretty amazed that it's so hard to accomplish – Michał Klimczak Dec 28 '11 at 19:09