How to keep third party 'Keys' secure in Android app - android

The next Android app I am creating uses third party APIs for: 1. Google API for geolocation. 2. Google APIs for Translation and 3. Zopim APIs for support chat.
Now almost all such service providers uses 'KEY' to uniquely identify who is requesting data. To implement these services I need to use the unique KEY they give me while I sign up.
Now the KEY is nothing but a String. What concerns me is, it is very easy to decompile APKs to source code. In that case, is it possible that somebody can use my app's APK to read the KEY and misuse it?
If yes, what is the solution to it? There are many apps out there that uses such KEYS from service providers. What do they do?

You can save those keys encrypted in your app server and send them securely via SSL on log in

Related

How to securely store 3rd Party API keys when back end is provided entirely by 'Back End As A Service'?

I am trying to develop a strategy for securing third party API keys for a React Native app. When building a web application, API keys can be stored in environment variables and then secured when deploying the application server.
However with a mobile app that only uses 'back end as a service' back end services, like Firebase, the app is not deployed, it is distributed and services are accessed.
After doing some research, it seems there is no standard / straight forward approach to solving this problem although it must be a situation that thousands of app developers find themselves in.
I am using Firebase, but also two other services that require API keys. My initial solution was to add these API keys (not Firebase keys) to Firebase environment variables as described here and then make a call in the app to a Firebase Cloud Function and to retrieve them. But I think the problem might be here that the keys can still be intercepted as they will be retrieved in plain text.
Is this a good approach to storing the third party keys, and if not, what other approaches could be taken?

How to store API credentials in android and avoid decompilation attack?

My end goal is to keep safe my API credentials and that cannot be discovered by decompiling the apk.
Currently, my API credentials are hardcoded at buid.gradle(app module) file.
When I decompiled my own apk using this site I can able to find the API url and other credentials.
Now I am looking for a solution and more interested to know how "google-services.json" file is getting parsed.
If there is a solution to read **my-cred.json** file under app folder at runtime or compile time (the same directory where **google-services.json** exists), I think I can protect my credentials from decompiling the source( correct me if I am wrong)
Please tell me a way to read **my-cred.json** or any other solution to protect the app credentials
In my opinion there is no way to protect this kind of private keys on your Android device. So the solution is simply not to store it on the Android device. But you can store it on an external server. In my case this key is used onyly once per session, to generate a session token. So I simply created a small java app that create the session token from the user id and the api key. That app is hosted on Google App Engine, but any hosting service should do the work. Then your Android app has to invoke this app (servlet) to get a proper token, which is then used to invoke the API.
I know this does not directly answer your question - but it's quite simple to put in place and will avoid your key to be reverse-engineered.
This is only a partial answer, but before you get into complex obfuscation methods, I would recommend you to first check for each API how they actually authenticate your app: Most API services today require you to register the certificate of your app to work, so even with your API key, one wouldn't be able to use the quota of your app since one wouldn't have access to the private key used to sign your app.
After some research i found out you can't reliably hide an app credential into an android app. Several solutions are being described but none of them is 100% secure , as it is pretty easy to reverse an android app.
You can only obfuscate to make an attacker loose time...
Here are some ways to obfuscate your app credentials , but none of them are really secure even the C++/JNI one. https://rammic.github.io/2015/07/28/hiding-secrets-in-android-apps/.
Only way to have it 100% secure is to set up your own server to hold the credentials and do the login for you, or even requests. I think the best way would be using an OAuth2 authentication process.
It depends on the time you have and your security needs.

Is this a practical method for securing a Mobile API?

I'm building a mobile API & library for logging analytics and have been exploring different methods of securing the API to prevent unwanted 3rd parties from logging data or intercepting user data.
My proposed method is to use public-key encryption: the user would generate the keys on the API's website, and be provided with the public/private key. The user would then manually store the key within the applications code, for example, in Android it could be a string resources file. When the app is run, the library will read the key provided by the user in code, encrypt the analytics data, and send it to the server, where it is decrypted and read.
After research I've discovered several problems with this method, most obviously that a 3rd party could de-compile the application and get the stored key (somehow?). However this seems like a lot of effort simply to get the key for analytics, which would only contain anonymous information. I also remember reading that another large developer (Twitter?) used a similar method, and changed the keys between app versions.
An alternative method could be to connect the user to the server, authenticate, then distribute keys for a session. However my application has nothing to uniquely identify and authenticate individual users (no user accounts & passwords), so I'd still need to store an identity for authenticating.
I'd really like a solution thats simple and easy for API users to implement, like copying a single encryption key, and also not bloated with network traffic for authenticating, managing sessions, distributing keys, etc. I would be interested to know how existing services such as Fabric and Firebase do it.

Best practices for API Key and Secret in bundled in App

I'm developing an app that will use text messages to verify a user's telephone number, the usual "enter code" routine.
After reading a little bit it seems like a bad idea to store the private keys for whatever 3rd party I'll use in the app (twilio, nexmo, etc). Somebody could reverse engineer these from my binary and use them in their app.
However, having these on the server doesn't help either, somebody could just reverse engineer my server's endpoint that I use to send text messages and use that instead.
E.g. I could reverse engineer WhatsApp and get the private keys or API endpoints that they use for telephone number verification and just use that in my app, saving me thousand of dollars.
Any ideas on how to protect myself against such an attack?
Hiding API Keys on the server
However, having these on the server doesn't help either, somebody
could just reverse engineer my server's endpoint that I use to send
text messages and use that instead.
Yes it does help a lot.
If somebody gets access to the keys to your web service, they can only do, what your service allows them to do. This is a very good idea to have a web service that encapsulates all the 3d party keys and API - it's way more secure.
Nobody will ever get access to your sensitive keys, that'll allow them to do everything.
For example the 3rd party API allows deleting - your server wrapper API will not allow it.
Moreover, you can add any extra logic or alerts for suspicious behavior.
Hiding API Keys in the app
If somebody sets their mind to it, there's no way you can prevent getting your keys reverse engineered from your app. You can only make that harder. Computer security should never be about "how hard/complicated it is to do", but in this case we have no choice.
Ok, so you have to hardcode the API keys into your source files. It can be easily reverse-engineered.
You can obfuscate your keys, so that they can't be read directly. The result will be that they'll be scattered in a compiled file, rather than comfortably being placed in one place.
On iOS you can use something like this.
On Android you can use DexGuard, or any other way to obfuscate a string.
Encrypting the keys
Another layer of making it hard for hackers is to encrypt the keys.
Here's an example for iOS.
You can do the same for Android.
Perfect Scenario
Ok, so let's say you have a 3rd party API for video management.
The hacker wants to delete all videos on the server, because the 3rd API allows that.
First he has to glue up all the scattered strings in the file. If he manages to do that, he has to find a way to decrypt that.
Even if he manages to decrypt that, that'll give him the API keys to your server and your server and your server only allows to upload videos, not delete them.
I think firebase functions can help us in hiding the third party API keys.
The proposed solution-
Store API keys in firebase as environment variables.
Make a firebase https function that answers to only the authenticated users. If an authenticated user requests it, the secret API key from the firebase environment variable is returned as the response.
Android app does an anonymous login into firebase for the first time, obtains the token.
This token is used as Authorization token in headers while requesting firebase https function. The firebase function would be something like https://us-central1-{your_project_name}.net/{function_name}
I have discussed the approach in detail in this blog and made a sample project

How can I hide my Parse.com API keys?

I develop a project with parse.com api. I use api key and client key
I use proguard to improve my app security if anybody can try decompile .apk
But in my app there is a API KEY and CLIENT KEY. How can I hide them or if anybody see those keys what happens?
thanks in advance
You can go through all sorts of machinations to obfuscate your Parse client key and app ID, but ultimately they're always going to be available to a clever person intent on discovering them. That's why protecting your data with proper ACL configurations is key. The suggestion of doing more in your Cloud functions is also a good idea if you want to hide details of your business logic which, if coded in your Android app, could be reverse engineered.
You should always assume those keys will become known, and secure your classes in Parse accordingly using Roles and ACLs.
For extra security use Cloud Functions that have extra security logic in them.

Categories

Resources