flutter_secure_storage: Unhandled Exception: PlatformException(Exception encountered, read, javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT

Issue is reproducible in release mode where an existing app backup is restored, using Google One or a rooted device.

This issue was being tracked in #161 and still exists in the latest version, yet the issue was closed and still remains closed to this day even after many people confirming the issue was never fixed in the replies.

E/flutter (23800): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: PlatformException(Exception encountered, read, javax.crypto.BadPaddingException: error:1e000065
:Cipher functions:OPENSSL_internal:BAD_DECRYPT
E/flutter (23800):      at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
E/flutter (23800):      at com.android.org.conscrypt.OpenSSLEvpCipher.doFinalInternal(OpenSSLEvpCipher.java:152)
E/flutter (23800):      at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:374)
E/flutter (23800):      at javax.crypto.Cipher.doFinal(Cipher.java:2055)
E/flutter (23800):      at com.it_nomads.fluttersecurestorage.ciphers.StorageCipher18Implementation.decrypt(StorageCipher18Implementation.java:103)
E/flutter (23800):      at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.decodeRawValue(FlutterSecureStoragePlugin.java:231)
E/flutter (23800):      at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.read(FlutterSecureStoragePlugin.java:213)
E/flutter (23800):      at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin.access$500(FlutterSecureStoragePlugin.java:37)
E/flutter (23800):      at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:302)
E/flutter (23800):      at android.os.Handler.handleCallback(Handler.java:938)
E/flutter (23800):      at android.os.Handler.dispatchMessage(Handler.java:99)
E/flutter (23800):      at android.os.Looper.loopOnce(Looper.java:201)
E/flutter (23800):      at android.os.Looper.loop(Looper.java:288)
E/flutter (23800):      at android.os.HandlerThread.run(HandlerThread.java:67)
E/flutter (23800): , null)

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 80
  • Comments: 36

Commits related to this issue

Most upvoted comments

If you use version 5.0.2, make sure you use this option when creating the instance:

FlutterSecureStorage(aOptions: AndroidOptions(
    encryptedSharedPreferences: true,
));

This causes the package to use Android’s built-in EncryptedSharedPreferences. The crash only seems to occur when not using this setting, because then the package uses a different way of encrypting and decrypting the prefs. You can see that by reading the source code here: https://github.com/mogol/flutter_secure_storage/blob/26efe91a75228ad8c8626d6eea18f7f3cb21bdd9/flutter_secure_storage/android/src/main/java/com/it_nomads/fluttersecurestorage/FlutterSecureStoragePlugin.java#L101

Also see https://github.com/mogol/flutter_secure_storage/pull/328#issuecomment-988577971

The current best workaround according to my research is:

  static Future<String?> getAccessTokenFromDevice() async {
    const _storage = FlutterSecureStorage();
    try {
      final accessToken = await _storage.read(key: 'accessToken');
      return accessToken;
    } on PlatformException catch (e) {
      // Workaround for https://github.com/mogol/flutter_secure_storage/issues/43
      await _storage.deleteAll();
    }
  }

This way you don’t have to lose out on the shared preferences being backed up like in the other suggestions which are honestly, a bit hacky.

It would be good if the library could be updated to handle this issue on its own?

Please, either open the previous issue or keep this one open. This is a major bug and should be tracked.

Still having this issue on v8.0.0

@NamanShergill Which version of the package are you using? Does this issue still persist?

5.0.2, and yes, it still happens.

Still an issue.

flutter_secure_storage 9.0.0 in Android 9.

The current best workaround according to my research is:

  static Future<String?> getAccessTokenFromDevice() async {
    const _storage = FlutterSecureStorage();
    try {
      final accessToken = await _storage.read(key: 'accessToken');
      return accessToken;
    } on PlatformException catch (e) {
      // Workaround for https://github.com/mogol/flutter_secure_storage/issues/43
      await _storage.deleteAll();
    }
  }

This way you don’t have to lose out on the shared preferences being backed up like in the other suggestions which are honestly, a bit hacky. It would be good if the library could be updated to handle this issue on its own?

A user with a pixel 4a had the same problem after a reinstall. deleteAll() did not help (I had this implemented already) only a manual clear of app data did.

Same here.

In our case, anything called through _storage is what gives the PlatformException. So, if we catch this exception and we try to call the .deleteAll() over the same _storage, the exception is thrown again and the App crashes completely 😭

If you use version 5.0.2, make sure you use this option when creating the instance:

FlutterSecureStorage(aOptions: AndroidOptions(
    encryptedSharedPreferences: true,
));

This causes the package to use Android’s built-in EncryptedSharedPreferences. The crash only seems to occur when not using this setting, because then the package uses a different way of encrypting and decrypting the prefs. You can see that by reading the source code here: https://github.com/mogol/flutter_secure_storage/blob/26efe91a75228ad8c8626d6eea18f7f3cb21bdd9/flutter_secure_storage/android/src/main/java/com/it_nomads/fluttersecurestorage/FlutterSecureStoragePlugin.java#L101

Also see #328 (comment)

Is there a way to enable this globally? We use storage in quite a few different widgets

Make a single storage object globally and use that

The current best workaround according to my research is:

  static Future<String?> getAccessTokenFromDevice() async {
    const _storage = FlutterSecureStorage();
    try {
      final accessToken = await _storage.read(key: 'accessToken');
      return accessToken;
    } on PlatformException catch (e) {
      // Workaround for https://github.com/mogol/flutter_secure_storage/issues/43
      await _storage.deleteAll();
    }
  }

This way you don’t have to lose out on the shared preferences being backed up like in the other suggestions which are honestly, a bit hacky.

It would be good if the library could be updated to handle this issue on its own?

A user with a pixel 4a had the same problem after a reinstall. deleteAll() did not help (I had this implemented already) only a manual clear of app data did.

Got same today

flutter_secure_storage: ^8.1.0

Continuo a riscontrare questo problema su v8.0.0

I also had the same problem as you on that version.

I just added to the manifest these rules on the application node to solve:

<application 
android:allowBackup="false" 
android:fullBackupContent="false" ...>

This causes the package to use Android’s built-in EncryptedSharedPreferences. The crash only seems to occur when not using this setting, because then the package uses a different way of encrypting and decrypting the prefs. You can see that by reading the source code here:

is it will be backward compatible if the user already has saved data or will crash?

If you use version 5.0.2, make sure you use this option when creating the instance:

FlutterSecureStorage(aOptions: AndroidOptions(
    encryptedSharedPreferences: true,
));

This causes the package to use Android’s built-in EncryptedSharedPreferences. The crash only seems to occur when not using this setting, because then the package uses a different way of encrypting and decrypting the prefs. You can see that by reading the source code here:

https://github.com/mogol/flutter_secure_storage/blob/26efe91a75228ad8c8626d6eea18f7f3cb21bdd9/flutter_secure_storage/android/src/main/java/com/it_nomads/fluttersecurestorage/FlutterSecureStoragePlugin.java#L101

Also see #328 (comment)

Is there a way to enable this globally? We use storage in quite a few different widgets

@NamanShergill Which version of the package are you using? Does this issue still persist?

5.0.2, and yes, it still happens.

I have a report from the sentry but can`t reproduce it. Do you get this error every time when trying to read from storage?

The reproduction method is restoring an app backup from Google after a factory reset/new phone setup or if you have root, through backup apps like Swift backup.

The error will show up everytime you try to access the storage, until the user manually clears the app data.

@NamanShergill Which version of the package are you using? Does this issue still persist?

5.0.2, and yes, it still happens.

I have a report from the sentry but can`t reproduce it. Do you get this error every time when trying to read from storage?