A Flutter plugin to store data in secure storage
The majority of us rely on our smartphones for practically everything we do on a daily basis. Many of us use our mobile phones for everything from taking photos of our WFH setup to ordering food, buying online, and banking.
As the number of digital products and services we use increases, so does the data saved on our devices, the chance of a security breach or data exposure to motivated attackers grows. This is where this flutter plugin comes in, providing secure storage to all the users.
Contents
flutter_secure_storage
Sensitive datas such as passwords, date of birth, bank account number, pins, email etc. can be securely kept encrypted on you local phones(iOS and/or Android) with the help of flutter_secure_storage plugin. Go on further to learn more!
Platform Implementation
Please note that this table represents the functions implemented in this repository and it is possible that changes haven’t yet been released on pub.dev
read | write | delete | containsKey | readAll | deleteAll | |
---|---|---|---|---|---|---|
Android | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
iOS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Windows | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Linux | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
macOS | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Web | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Getting Started
If not present already, please call WidgetsFlutterBinding.ensureInitialized() in your main before you do anything with the MethodChannel. Please see this issue for more info.
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // Create storage final storage = new FlutterSecureStorage(); // Read value String value = await storage.read(key: key); // Read all values Map<String, String> allValues = await storage.readAll(); // Delete value await storage.delete(key: key); // Delete all await storage.deleteAll(); // Write value await storage.write(key: key, value: value);
This allows us to be able to fetch secure values while the app is backgrounded, by specifying first_unlock or first_unlock_this_device. The default if not specified is unlocked. An example:
final options = IOSOptions(accessibility: IOSAccessibility.first_unlock); await storage.write(key: key, value: value, iOptions: options);
Important notice for Android and v5.0.0
When upgrading from 4.2.1 to 5.0.0 you can migrate to EncryptedSharedPreferences by setting the encryptedSharedPreference parameter to true as explained below. This will automatically migrate all preferences. This however can’t be undone. If you try to disable encryptedSharedPreference after this, you won’t be able to read the values. You can only read those with encryptedSharedPreference enabled.
Important notice for Web
flutter_secure_storage only works on HTTPS or localhost environments. Please see this issue for more information.
A Flutter plugin to store data in secure storage:
- Keychain is used for iOS
- AES encryption is used for Android. AES secret key is encrypted with RSA and RSA key is stored in KeyStore
- With v5.0.0 we can use EncryptedSharedPreferences on Android by enabling it in the Android Options like so:
AndroidOptions _getAndroidOptions() => const AndroidOptions( encryptedSharedPreferences: true, );
For more information see the example app.
libsecret
is used for Linux.
Note KeyStore was introduced in Android 4.3 (API level 18). The plugin wouldn’t work for earlier versions.
Configure Android version
In [project]/android/app/build.gradle
set minSdkVersion
to >= 18.
android {
...
defaultConfig {
...
minSdkVersion 18
...
}
}
Note By default Android backups data on Google Drive. It can cause exception java.security.InvalidKeyException:Failed to unwrap key. You need to
- disable autobackup, details
- exclude sharedprefs
FlutterSecureStorage
used by the plugin, details
Configure Web Version
Flutter Secure Storage uses an experimental implementation using WebCrypto. Use at your own risk at this time. Feedback welcome to improve it. The intent is that the browser is creating the private key, and as a result, the encrypted strings in local_storage are not portable to other browsers or other machines and will only work on the same domain.
It is VERY important that you have HTTP Strict Forward Secrecy enabled and the proper headers applied to your responses or you could be subject to a javascript hijack.
Please see:
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
- https://www.netsparker.com/blog/web-security/http-security-headers/
Configure Linux Version
You need libsecret-1-dev
and libjsoncpp-dev
on your machine to build the project, and libsecret-1-0
and libjsoncpp1
to run the application (add it as a dependency after packaging your app). If you using snapcraft to build the project use the following
parts: uet-lms: source: . plugin: flutter flutter-target: lib/main.dart build-packages: - libsecret-1-dev - libjsoncpp-dev stage-packages: - libsecret-1-dev - libjsoncpp-dev
Configure MacOS Version
You also need to add Keychain Sharing as capability to your macOS runner.
Integration Tests
Run the following command from example
directory
flutter drive --target=test_driver/app.dart
GitHub
Source Code: flutter secure storage.