All ways to protect data


This article will tell you in what general ways you can protect your application from being hacked or getting personal information by third parties by following a few simple steps, but it is worth remembering that there are no things that cannot be hacked, it all depends on the time spent and the motivation of the hacker, but because Since our goal is to secure our application, let’s make life as difficult for them as possible.


Part 1: Update to latest versions

Upgrading to the latest version of the framework, language, and libraries used can include performance gains, more features, and of course, more security, let’s not neglect this advice.

To see the current versions of the framework and language, you need to enter the following command in the console:

flutter doctor -v

Command to update Flutter and Dart SDK to latest stable versions:

flutter upgrade

Use a package manager or other tool to update your project’s libraries and dependencies.

Part 2: Obfuscation

Code obfuscation is the process of changing the binary code of an application to make it harder for people to understand. Obfuscation changes the names of functions and classes in your compiled code into something meaningless to a human but not to a machine, but it will be much more difficult for people trying to reverse engineer your code. The Dart language has obfuscation mechanisms and supports them for the following platforms:

Android / iOS / macOS – supported.
Linux / Windows – not supported.
Web – not supported, but the code is automatically minified.

Code obfuscation is done only for release versions!

To enable obfuscation, you need to specify the following parameters when creating an apk:

--obfuscate --split-debug-info=//

For example:

flutter build apk --obfuscate --split-debug-info=build/app/outputs/symbols

--obfuscate – is responsible for enabling obfuscation in your application.

--split-debug-info=// is a debug character map, when your application crashes, the Google Play Developer Console will log this crash so that you can check and debug, but since the end user has a version with obfuscation enabled, the report sent will be written with meaningless names and there will be no way debug it. This is exactly what the debug character map is for, which will be used internally by the Play Console to convert the crash report characters into human-readable names so that the application can be debugged.

Having debug symbols inside the application does not affect or help outsiders hack your application!

Moreover, the presence of this parameter can even reduce the final size of the apk down to 0.5mb.

Minimization (minification) is the process of removing all unnecessary characters from the source code of interpreted programming languages ​​or markup languages ​​without changing its functionality. These unnecessary characters typically include spaces, newlines, comments, and sometimes block separators, which are used to improve the readability of the code but are not required to run it. Minimization reduces the size of the source code, making it more efficient to transmit over the network.

JavaScript example:

// Этот комментарий будет убран после минимизации
var array = [];
for (var i = 0; i < 20; i++) {
  array[i] = i;

Same thing, but after minimization:

for(var a=[i=0];i<20;a[i]=i++);

Part 3: Login Screen

Using the login-login mechanism is essential to improve the security of your application from unwanted logins. Depending on the type of your application (offline or online), the methods used to implement authorization will differ.

If you have an offline application:

  • passcode_screen — package for Android and iOS, registration-login menu.

  • Write your offline authorization mechanism.

If you have an online application:

  • google_sign_in — package for Android and iOS, sign in with Google.

  • Use firebase.

  • Use your server.

You can use not only a password, but also biometric authorization, for example, by fingerprint, face, etc., the following plugin can help with this:

local_auth – for Android and iOS, supports fingerprint authentication, touch ID, face ID, pin code…

Part 4: Hashing

We have already talked about the authorization screen, and since. under any condition it uses some kind of “password”, then we need to protect it somehow. For these purposes, I recommend familiarizing yourself with the hashing process.

Hashing is the process of converting any amount of information into a unique set of characters that is unique to this array of incoming information. This set of characters will be called a hash.

An example of hashing the word “Brain” using the SHA-1 algorithm:


The main essence of this process is that in the database we will store not the password itself, but its hash, and so on. the hash cannot be converted back, then the cracker will not be able to find out the password, it turns out that we will send not the password, but its hash, and compare the hash of the entered password with the hash value in the database.

Hashing can be used not only for a password, but also for any information that you do not need to decrypt back, but simply compare with some value for confirmation.

To take advantage of hashing, you can use the following package:

crypto – supported algorithms: SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256, MD5, HMAC (HMAC-MD5, HMAC-SHA1, HMAC- SHA256).

An example of a string hashing function using the SHA-512 algorithm (Dart language):

  static String hashSHA512(String text) {
    return sha512.convert(utf8.encode(text)).toString();

Part 5: Databases

Before developing any application, you need to decide how the data will be stored, using Flutter we have a fairly extensive choice in this matter, if we are talking about storing data online, then this is a cloud or remote servers, and if we are talking about offline, then this is a local database . In either case, it is certainly better to choose a database with built-in security.

Local (offline) databases:

  1. Shared Preferences – the usual storage for application settings for the Android platform, the plugin also includes the standard storage for iOS. Weak data protection mechanisms. Suitable for storing key-value pairs of small amounts of data.

  2. Flutter Secure Storage – improved version of Shared Preferences, has encryption, but it is turned off by default. Also suitable for storing key-value pairs of small amounts of data.

  3. hive – NoSQL database with a built-in AES-256 encryption mechanism.

  4. Isar – NoSQL database, improved version of Hive, new features added and performance increased, use of the built-in AES-256 encryption mechanism is optional.

  5. ObjectBox – NoSQL database, the main positive aspects of this database are the speed and the ability to synchronize data between devices and servers, it does not have encryption.

  6. SQFlite – SQL database, an analogue of SQLite for Flutter, does not have encryption.

Thus, we can take a database with built-in security and use it, or take it without built-in security and independently encrypt the sent data and decrypt the received data. I would also like to draw attention to the Flutter Secure Storage plugin, it is ideal for additional protection of keys, passwords, etc. that we store locally on the device.

Part 6: Encryption

Encryption is the process of encoding information to prevent unauthorized access. In the event of a theft or leak, the encrypted data will be unreadable without the corresponding key.

To implement encryption in Flutter, I suggest using the following package:

encrypt — supports Salsa20, RSA, AES algorithms (CBC, CFB-64, CTR, ECB, OFB64, OFB-64/GCTR, SIC modes).

Plugin usage example (Dart language):

import "package:encrypt/encrypt.dart";
import "package:encrypt/encrypt.dart" as encrypt;
import "package:flutter_secure_storage/flutter_secure_storage.dart";

class AES {
  static const storage = FlutterSecureStorage(
      aOptions: AndroidOptions(encryptedSharedPreferences: true));
  static late final key;
  static late final iv;
  static final enc =
      encrypt.Encrypter(encrypt.AES(Key.fromBase64(key), mode: AESMode.cbc));

  static void initAES() async {
    storage.write(key: "password", value: null);
    storage.write(key: "key", value: encrypt.Key.fromSecureRandom(32).base64);
    storage.write(key: "iv", value: encrypt.IV.fromSecureRandom(16).base64);
    key = await "key");
    iv = await "iv");

  static void readAES() async {
    key = await "key");
    iv = await "iv");

  static encryptAES(text) {
    return enc.encrypt(text, iv: IV.fromBase64(iv)).base64;

  static decryptAES(text) {
    return enc.decrypt(Encrypted.fromBase64(text), iv: IV.fromBase64(iv));

The example above uses the AES CBC algorithm and an additional database Flutter Secure Storage with its own encryption enabled to store the keys to the underlying encryption mechanism. The “base64” and “fromBase64” prefixes are used to work with strings.

Part 7: Root Devices

Root or superuser is a special account in the system, the owner of which has the ability to perform absolutely any operation in the system.



Because Since we have a goal – to protect our application, then we must refuse to support root devices. To do this, we need to know if the user’s device has root rights, the following plugins will help us with this:

root (Android only).

root_check (Android only).

If the user still has extended rights, then now we can impose any restrictions on him in our application, or simply immediately terminate the application:

SystemNavigator.pop() – only for Android.

exit(0) – for Android and iOS (iOS may begin to suspect your application, use is undesirable).

iOS does not have proven tools for intentionally exiting an application, but the following plugin can be used:

minimize_app – for Android and iOS, will allow you to throw a working application into the background (minimize it).


This article has provided the most general tips on how to secure any application written with Flutter. Summarize:

Part 1: Updating to the latest versions – General protection update.
Part 2: Obfuscation vs Reverse Engineering.
Part 3: Authorization screen – from unauthorized entry by another person.
Part 4: Hashing – from interception and password guessing.
Part 5: Databases – for data protection.
Part 6: Encryption – from unwanted reading of personal data.
Part 7: Rooted devices – from logging into the app on rooted devices.

If you have more ideas, then write them in the comments and I will update the article.

Similar Posts

Leave a Reply