With the increasing amount of sensitive data being stored on mobile devices, security has become a major concern for developers and users alike. One question that often comes up is how to store sensitive keys securely on mobile devices. In this article, we will explore the various ways in which sensitive keys can be stored and the best practices to follow to keep them secure.
When a private key leaves the backend server, it is no longer securely stored and is up for grabs by anyone with the skills and knowledge to use reverse engineering tools. Client-side applications cannot use private keys, only public ones. Decompiling or reverse-engineering the app is one way to view sensitive keys. There are many reverse engineering tools available on the market, free and paid ones.
So, is there a way to harden the app against such attacks? Yes, code obfuscation is one method that can be used to make it more difficult for attackers to reverse engineer the app. Code obfuscation is the process of making the code more difficult to understand and reverse engineer. However, it is important to note that this is not a foolproof method and can only make it more difficult for attackers to view the sensitive keys.
It is also a poor security practice to store secrets in an app. The best answer is to have some sort of user authentication, but that doesn’t work for APIs that don’t have a user. Beyond that, you can encrypt sensitive data. Then you either need to put the encryption key in the app or need to get it from an (intercept-able) API call.
However, ultimately, it boils down to how frustrating you want to make it for an attacker to get the key. For less sensitive data, such as Google Maps keys, it may be fine to store them as is. For more sensitive data, you can use a “calculated” key and create it through an algorithm to make it more difficult to find and extract. But nothing is 100% attack-proof because you always give the attacker everything they need if it’s part of your build.
It is recommended to avoid putting very sensitive data into your .env file for both mobile and web platforms. Even if you replace the env variables ahead of time into the code and obfuscate your code, those variables are still retrievable via file/bundle inspection. It’s just a certain degree of more effort. .env should be used to host non-sensitive data for the front end of your application. Operations that involve truly sensitive keys should be proxied through an API call to a service that can securely host and use these values.
As a side note, for beginners, Flutter secure storage is the package for encrypting the plain text input on runtime.
In conclusion, storing sensitive keys on mobile devices is a complex issue that requires careful consideration and planning. Developers should follow best practices, such as using encryption, avoiding storing sensitive data in the app, and using code obfuscation to make it more difficult for attackers to reverse engineer the app. Ultimately, the best approach is to proxy operations that involve truly sensitive keys through an API call to a service that can securely host and use these values. By taking these steps, developers can help ensure that sensitive data is protected on mobile devices.
There’s a deeper answer in this SO thread: https://security.stackexchange.com/questions/100129/what-to-do-when-you-can-t-protect-mobile-app-secret-keys
Take a look at a general topic called code obfuscation https://en.wikipedia.org/wiki/Obfuscation_(software).
Now, specific for Dart: https://docs.flutter.dev/deployment/obfuscate.
But quoting the Flutter docs:
It is a poor security practice to store secrets in an app.
Useful reference link:
https://developer.okta.com/blog/2019/01/22/oauth-api-keys-arent-safe-in-mobile-apps.
https://stackoverflow.com/questions/59556927/how-to-secure-secret-keys-in-android-app.
https://guides.codepath.com/android/storing-secret-keys-in-android.
https://systemweakness.com/why-not-to-use-dotenv-on-flutter-5d3a07abc971