Best Way to Secure Android App Sensitive Data

Best way to secure Android app sensitive Data?

Storing sensitive data on the device

That depends very much on your audience. Normally, the Android OS prohibits apps from accessing each other's files (i.e. databases, preference files, regular files stored in the app's private directory) through proven Linux file permissions. However, on rooted devices an application can obtain root access and read everything. A few things to think about:

  1. If you know your users won't have root (e.g. if you are not distributing the app through Android Market, but only in your company, or something like that), you can simply rely on Android's filesystem-based security.
  2. If a user does get root access, he will be very careful what application he gives that priviledge to
  3. If an app does get root access, it can wreak a lot of havoc. The information in your app could be the least of the user's worries.
  4. Rooting leads to zero warranty. Including in apps. You can't be held responsible for leaking information on a rooted phone.

To conclude, if your information is not super-duper sensitive (e.g. credit card information), I'd suggest just sticking with the default security provided by Android (i.e. save everything in plain text, knowing other apps can't access it).

Otherwise, encryption is the way to go. It's not 100% secure (a hacker could de-compile your app and figure out how to decrypt the data), but it's a major pain to crack and will stop most hackers. Especially if you obfuscate your code with something like ProGuard.


Transferring sensitive data from the server to the device

You have a few options here. First of all, always use HTTPS. After enabling HTTPS, here are two extra security measures I would propose:

  1. Use an API key system. Include this API key in all your requests and check it on the server side before sending any response back. Remember that since you're using HTTPS, an attacker would not be able to just use a network sniffer to find out your API key. However, this is pretty easy to figure out if someone decompiles your app, which is why you can obfuscate it even further (besides using ProGuard). For example, you can keep the API key broken up into pieces all around your code (for example as static members in two or three classes). Then, when you send a request, you just concatenate all those pieces. You can even apply some other sort of transformation (e.g. bit shifting) to make it even harder to figure out from the decompiled code.
  2. You can generate a key every time you send a request. That key would be generated by using a bit of logic that only you know, so that you can implement it client- and server-side as well. For example, a request could include the following parameters:

    time=1321802432&key=[generated-key]
    where generated-key is generated from the time parameter. For example: md5(time + salt). When the server receives this request, it can do two things:

    1. Check that key is indeed equal to md5(time + salt) (note that only the client and the server know the salt and it can be obfuscated similarly to the API key above), and
    2. Check that time is not too far back in the past (e.g. if it's more than 1-2 minutes in the past, consider the request invalid).

The second method is more useful if you are also doing plain HTTP requests, where everyone can see the parameters being sent. Also, it's much harder to figure out from decompiled code. Especially if you spread the key calculation logic across multiple classes.

However, note that nothing makes it impossible to crack your app. You can obfuscate as much as you want, if a hacker is really determined to get to your data, he will be able to so by decompiling your application and spending many sleepless nights passing through your code and figuring out how the requests are formed. The only real way of securing your data is by asking your user for a password, besides doing all the work I wrote about above. You can't get a password that only exists in someone's (the user) head from decompiled code :).

Most secure way of sending data between activities in Android

Putting the data in the Intent would be the least secure, insofar as that data is being sent by IPC from your process to a core OS process, then back to your process via another IPC invocation. On modern versions of Android, I know of no security issues with this — other apps cannot spy on that IPC or otherwise get at that data. However, all else being equal, keeping the sensitive data within your process at all times would be more secure than passing that data outside of your process.

The cited "Persist objects (sqlite, share preferences, file, etc.)" is not a way of passing data between components. It is a way of persisting data for long-term use. Now, most apps need such persistence, and so you may have persistence for other reasons and simply leverage it (e.g., A triggers writing data; E reads in that data). From an efficiency standpoint, though, disk I/O is slow, and so you do it when you need persistence, not data passing.
Typically, though, with persistence, we maintain some sort of in-memory cache, to minimize that disk I/O. That involves static fields and WeakReferences, the other option cited in that Stack Overflow answer.

Off the cuff, and knowing nothing about your app:

  • If this sensitive data should be persisted, then just persist it, use a cache, and have E get the data from the cache or persistent store

  • If this sensitive data should not be persisted, but it is large and it can be acquired again (e.g., via network I/O), cache it using a static field and a WeakReference, so you do not tie up heap space indefinitely

  • If this sensitive data should not be persisted, and either is not large or cannot readily be acquired again, cache it using a static field, so it sticks around as long as your process does

How to secure our app

Behind every great mobile app is a great backend, but building a REST API for your app can be a bit daunting if you haven’t done so before. Fear not! I suggest you to find some tutorial about how to build your REST API using Node.js, and connect it to an iOS or Android app!, and handle authentication. Some reasons to use Node JS as backend.

  • It’s easy to work with JSON in JavaScript!
  • Node.js is lightweight and easy to get started with.
  • Node.js gives you fine-grained control over your request and responses.

How secure sensitive data in react-native app

Exchanged one Problem with Another

In my application I have a connection with keycloak for get an API key and a secure storage to save the user data.

So, using KeyCloak to retrieve the API Key at runtime in order to not have it harcoded in the mobile app, just shifts the problem from securing the API key to securing the KeyCloak secret.

Extracting Secrets from the Mobile App

How I can secure :

  • the secret id need to connect to the keycloak
  • the key to access the secure store

The cruel truth is that you can't properly secure them, because any secret you ship in a mobile app release must be considered as belonging to the public domain, because it's on the client side, therefore anyone can spend the time he/she wants to reverse engineer the mobile app with static or dynamic analysis to extract it.

You can hide the secret in Natice C code with the use of JNI/NDK as I show in the article How to Extract an API key from a Mobile App with Static Binary Analysis:

The range of open source tools available for reverse engineering is huge, and we really can't scratch the surface of this topic in this article, but instead we will focus in using the Mobile Security Framework(MobSF) to demonstrate how to reverse engineer the APK of our mobile app. MobSF is a collection of open source tools that present their results in an attractive dashboard, but the same tools used under the hood within MobSF and elsewhere can be used individually to achieve the same results.

Now, with the secret hidden in the native C code it will be time consuming to extract it, but not impossible. So, if you cannot do it easily with statically reverse engineer it, then you can do it with a MitM attack as I show in the article Steal that Api Key with a Man in the Middle Attack:

In order to help to demonstrate how to steal an API key, I have built and released in Github the Currency Converter Demo app for Android, which uses the same JNI/NDK technique we used in the earlier Android Hide Secrets app to hide the API key.

So, in this article you will learn how to setup and run a MitM attack to intercept https traffic in a mobile device under your control, so that you can steal the API key. Finally, you will see at a high level how MitM attacks can be mitigated.

Do you get the the twist? You can make it very hard to extract with static binary analysis, but then the attacker just needs to use a tool like mitmproxy to intercept the traffic and lookup the API key in the header of the request.

You can try to safeguard your mobile app against MitM attacks has I exemplify in my article Securing HTTPS with Certificate Pinning:

In order to demonstrate how to use certificate pinning for protecting the https traffic between your mobile app and your API server, we will use the same Currency Converter Demo mobile app that I used in the previous article.

In this article we will learn what certificate pinning is, when to use it, how to implement it in an Android app, and how it can prevent a MitM attack.

But, you need to be aware that you can also bypass pinning as I show in the next article Bypass Certificate Pinning:

To demonstrate how to bypass certificate pinning we will use the same Currency Converter Demo mobile app that was used in the previous article.

In this article you will learn how to repackage a mobile app in order to make it trust custom ssl certificates. This will allow us to bypass certificate pinning.

Other alternative for the attacker is to use an instrumentation framework to hook into the code that returns the secret or API key from the keystore or from KeyCloak server. A popular instrumentation framework used for this type of attack is Frida:

Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.

So, the use of Frida to hookup in the code is made easier when the code is not obfuscated, because it's easy to find the function that does it by doing some search through the code with some guessable function names, or just resort to follow the code flow with the help of an IDE.

Code Obfuscation and it's importance

It's possible to obfuscate the code but it's not a serious solution and this has a great impact on performance.

Yes, you are right that code obfuscation will not hide the secret, only makes it hard to understand the logic flow.

Code obfuscation should still be in your list of security hardening your mobile app, and once used as Google recommends, by shrink code and resources, obfuscate, and optimize your app with R8, and then you will not have a slower app just because the code is obfuscated, but you will have one that is much harder to follow the logic through the code, thus an attacker poking around the code to find were to hook an instrumentation framework will have a much more consuming time task, to not call it frustrating sometimes.

Securing the Secrets in the Mobile App

I read different article but I didn't find a way to properly secure those data. A simple revert engineering from the APK show the secret data.

Yes, you cannot find one because that's not a trivial problem to solve, you can only make it hard, but not impossible.

The Difference Between WHO and WHAT is Accessing the API Server

Before I dive into the possible approaches to solve your problem I would like to first clear a misconception that usually I find among developers of any seniority, that is about the difference between who and what is accessing an API server.

I wrote a series of articles around API and Mobile security, and in the article Why Does Your Mobile App Need An Api Key? you can read in detail the difference between who and what is accessing your API server, but I will extract here the main takes from it:

The what is the thing making the request to the API server. Is it really a genuine instance of your mobile app, or is it a bot, an automated script or an attacker manually poking around your API server with a tool like Postman?

The who is the user of the mobile app that we can authenticate, authorize and identify in several ways, like using OpenID Connect or OAUTH2 flows.

So think about the who as the user your API server will be able to Authenticate and Authorize access to the data, and think about the what as the software making that request in behalf of the user.

Now that you are better informed about the difference between them you can make better informed decisions in terms of security and trade-offs when deciding waht approaches to take for your use case.

A Possible Naive Approach

  • Hide your API Key or if you prefer the KeyCloak secret in Native C Code as I show in the article I linked above that references this Github repo. This makes static reverse engineer the secret harder.
  • Shrink code and resources, obfuscate, and optimize your app as per Google instructions.This makes it hard to find the code were to hook Frida.
  • Implement certificate pinning. This makes it harder to perform a MitM attack.

I call it naive approach, because has I shown in my series of articles I linked it can be bypassed, but it raises the bar for the skill set and time necessary to do it.

A Possible Better Solution

So, your main goal seems to be to protect the API key, that you need to use as a way to identify your mobile app with the backend API server, aka to lock down the backend API server with the genuine and untampered versions of your mobile app, that will allow for the server to only answer to requests from the same binary that you uploaded to Google Play store, then you may want to take a look into the Mobile App Attestation concept, and to for that I recommend you to read this answer I gave to the question How to secure an API REST for mobile app?, especially the sections Securing the API Server and A Possible Better Solution.

In a nutshell the role of a Mobile App Attestation solution is to guarantee at run-time that your mobile app was not tampered with, is not running in a rooted device, not being instrumented by a framework like xPosed or Frida, not being MitM attacked, and this is achieved by running an SDK in the background. The service running in the cloud will challenge the app, and based on the responses it will attest the integrity of the mobile app and device is running on, thus the SDK will never be responsible for any decisions.

Do You Want To Go The Extra Mile?

In any response to a security question I always like to reference the excellent work from the OWASP foundation.

For APIS

OWASP API Security Top 10

The OWASP API Security Project seeks to provide value to software developers and security assessors by underscoring the potential risks in insecure APIs, and illustrating how these risks may be mitigated. In order to facilitate this goal, the OWASP API Security Project will create and maintain a Top 10 API Security Risks document, as well as a documentation portal for best practices when creating or assessing APIs.

For Mobile Apps

OWASP Mobile Security Project - Top 10 risks

The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.

OWASP - Mobile Security Testing Guide:

The Mobile Security Testing Guide (MSTG) is a comprehensive manual for mobile app security development, testing and reverse engineering.

Securely Storing Sensitive Data from App on Remote Server

Disclaimer

I'm not a security professional. I'm not an expert. I'm just some random developer on the internet who's done some reading in the past and took a stab at answering your question. Head over to the information security stackexchange if you want more reliable information.


A user enters sensitive information into your program. You want them to be able to recover it later, so you must save it somewhere. How to handle this?

Where to save it?

  • On the device if it doesn't need to be accessible from elsewhere.
  • On a server if the user might need to access it from a different device (or recover it).

How to secure it?

  • Encrypt it.

What to encrypt it with?

  • A standard, secure algorithm (such as AES), and a key derived from a user provided password.

But users tend to come up with poor passwords. If we're sending this to a server, and the database might be compromised, how to protect against brute force attacks?

  • Employ a key stretching algorithm, such as PBKDF2.

How secure is this, really?

  • Well if the user picks a poor password, and then your database is compromised, brute force will be relatively easy.
  • If the password ever leaves their device (like if you, say, reused the same password for the app to log in to your servers or something) then you're treading in dangerous waters.

Secure way to store sensitive information in Android

Unfortunately the commenters are correct. There is no way to guarantee with 100% security that the activation code can't be hacked. Microsoft has spent millions of dollars on this, and there are still pirated copies of Windows out there, because at the end of the day you have no control of the code on the client. If you endow the client with the ability to decrypt or otherwise access this stored authentication code (without needing to go to the server), then someone can reverse engineer the app to undo your protection. This is true even if you retrieve a decrypt key from the server.

The best way to do this depends on your use case, but here are some ideas:

  1. Have the client submit the "activation code" to the server, where you can blacklist it if you think it's stolen. This is how Windows works. This is the only option you have if you want to use an activation code and not bother the user.

  2. Have the user register an account and have the app resubmit the user's credentials each time it runs. This way you have a user account to deactivate if you suspect piracy.

  3. Have the server provide the decrypt key. This does not guarantee that the activation code stays safe, but it does up the bar for potential reverse engineers.

  4. Drop the whole DRM idea completely, and focus your attention on making a good product. Studies that music companies have shown that dropping the DRM makes no difference in the number of people who buy your product.



Related Topics



Leave a reply



Submit