A Flutter plugin to store data in secure storage:
For more information see the example app.
libsecret
is used for Linux.AndroidOptions _getAndroidOptions() => const AndroidOptions(
encryptedSharedPreferences: true,
);
But Jetpack security crypto library is deprecated. So, we recommend using the default implementation or DataStore.
DataStore support has been available since v10.0.0. When using DataStore, set the options as follows.
AndroidOptions _getAndroidOptions() => const AndroidOptions(
dataStore: true,
);
If you want to stop using EncryptedSharedPreferences, use the following option to migrate from EncryptedSharedPreferencs to DataStore. As previous implementations did not envisage migration from EncryptedSharedPreferences to SharedPreferencs, only the migration option to DataStore is implemented.
AndroidOptions _getAndroidOptions() => const AndroidOptions(
encryptedSharedPreferences: true,
dataStore: true,
);
Note: that support for EncryptedSharedPreferences is planned to be removed in v11.
flutter_secure_storage only works on HTTPS or localhost environments. Please see this issue for more information.
Supported from v2.0.0.
dependency_overrides:
flutter_secure_storage_x_web: ^2.0.0
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 | isCupertinoProtectedDataAvailable | onCupertinoProtectedDataAvailabilityChanged | |
---|---|---|---|---|---|---|---|---|
Android | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | ||
iOS | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
Windows | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | ||
Linux | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | ||
macOS | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: (on macOS 12 and newer) |
Web | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
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_x/flutter_secure_storage_x.dart';
// Create storage
final storage = 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: KeychainAccessibility.first_unlock,
);
await storage.write(
key: key,
value: value,
iOptions: options,
);
In [project]/android/app/build.gradle
set minSdkVersion
to >= 23.
android {
...
defaultConfig {
...
minSdkVersion 23
...
}
}
Note By default Android backups data on Google Drive. It can cause exception java.security.InvalidKeyException:Failed to unwrap key. You need to
FlutterSecureStorage
used by the plugin, detailsFlutter 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:
On the web, all keys are stored in LocalStorage. flutter_secure_storage has an option for the web to wrap this stored key with an application-specific key to make it more difficult to analyze.
final _storage = const FlutterSecureStorage(
webOptions: WebOptions(
wrapKey: '${your_application_specific_key}',
wrapKeyIv: '${your_application_specific_iv}',
),
);
This option encrypts the key stored in LocalStorage with WebCrypto wrapKey. It is decrypted with WebCrypto unwrapKey when used. Generating and managing application-specific keys requires careful attention from developers. See (https://github.com/mogol/flutter_secure_storage/issues/726) for more information.
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-0
- libjsoncpp-dev
Apart from libsecret
you also need a keyring service, for that you need either gnome-keyring
(for Gnome users) or ksecretsservice
(for KDE users) or other light provider like secret-service
.
You also need to add Keychain Sharing as capability to your macOS runner. To achieve this, please add the following in both your macos/Runner/DebugProfile.entitlements
and macos/Runner/Release.entitlements
(you need to change both files).
<key>keychain-access-groups</key>
<array/>
If you have set your application up to use App Groups then you will need to add the name of the App Group to the keychain-access-groups
argument above. Failure to do so will result in values appearing to be written successfully but never actually being written at all. For example if your app has an App Group named "aoeu" then your value for above would instead read:
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)aoeu</string>
</array>
If you are configuring this value through XCode then the string you set in the Keychain Sharing section would simply read "aoeu" with XCode appending the $(AppIdentifierPrefix)
when it saves the configuration.
You need the C++ ATL libraries installed along with the rest of Visual Studio Build Tools. Download them from here and make sure the C++ ATL under optional is installed as well.
Run the following command from example
directory
flutter drive --target=test_driver/app.dart
If you want to contribute, you need to initialise the workspace after cloning the repo with melos
like this:
flutter pub get
melos bootstrap
After that, everything should be set up and working!