How to protect webservice calls in Android

Hello, I’m working on an android application in which I need to run several https services, so the entire URL of the web service and the KEY web API key are in the code plus the server IP address. When someone does the reverse engineering of my application, then this guy can get the URL of the web service as well as the KEY API, and then just hit it with the rest client.

How to ensure that any attacker could not get any of my WEB API KEY, which I defined in strings.xml

 <string name="WEB_API_KEY">XXXXXXXXXXXXXXXXXXXXXXXXXXX</string> 

Thanks in advance.

+5
source share
5 answers

I ran into the same problem. First, make sure that this application that I created calls only the web service. even if they get the key to worshiping technology. secondly, the actual user invokes the application. The following checks are performed on the server.

1) Make sure it is truly signed by Google.

2) Make sure that it is really intended for you.

you need to use the Google developer console https://console.developers.google.com/project?authuser=0 create two client identifiers (one for the server and the other for the Android application.) in the API and auth menus. To create a client ID for an Android application, you can use keytool keytool -exportcert -alias <your-key-name> -keystore <your-key-store-file> -v -list

I followed the steps here

A sample server php is shown below.

 function checkSession($token){ $result = Array(); if(isset($_SERVER['HTTPS'])) { if ($_SERVER["HTTPS"] == "on") { $secure_connection = true; } } if($secure_connection){ try { $client = new Google_Client(); $client->setClientId(CLIENT_ID); $client->setClientSecret(CLIENT_SECRET); $ticket = $client->verifyIdToken($token); $validtocken = false; if($ticket){ $token_data = $ticket->getAttributes(); if($token_data ["payload"]["aud"]==CLIENT_ID && $token_data ["payload"]["azp"]==ANDROID_ID){ $validtocken = true; $result["Email"]=$token_data ["payload"]["email"]; } else { log_message(serialize($token_data)); } } } catch (Exception $e) { $result["Details"]=$e->getMessage(); } } 
+4
source

The best way to get the web api key from the server when you first open the application .

In this case, the application stores the key in the internal storage, and not in apk.

+1
source

You cannot rely on anything solid in your code to determine if a request is coming from your application or rogue customer. You must have the web service require some kind of verification before it accepts any request. An example is a pair of users / passwords, or forcing a web service to accept / reject clients based on their SSL certificate. Thus, only authorized users will use the web service.

0
source

Storing API_KEY in the application is not a good idea; it can be easily undone, especially if it was in XML resources. You must send it to the server and then call the service.


App --- Call ---> [Service1.php, which has API_KEY] --- Call → Payment service.

App <--- Response --- [Service1.php] <--- Response ---- Payment service.

This is similar to the presence of intermediate layers between the payment service and your application. Thus, the hacker cannot get the key to the key.

0
source

Protecting an application only with hard-coded credentials, as already mentioned, is not secure.

I should suggest you use some login structure. Where do you first ask for a username / password.

Then you create a upp API call using a signature that you compile at runtime. By doing this, you never need to send users password over an open network.

You can achieve this by calling as follows:

 APIkey = "a specicic APIkey"; //To identify the specifik app "not secret" Username = "usersname"; //To identify witch user trying to make the call Request = "you needed request data"; //Your actual requst parameters. Timestamp = "Current_timestamp"; //Current timestamp user to get unique signatures for every call Signature = sha256_hash(APIkey + Username + Request + Timestamp + Password); //Signature using the users password(Secret). 

You can then verify the call by recompiling the name server, as well as using the saved password in your database. If the signatures match, the call must be authentic. You should also set timelimit and reject every call that is old.

Note: you probably need to adapt and change it to working code in your language, but you get this idea.

0
source

Source: https://habr.com/ru/post/1205042/


All Articles