mogol / flutter_secure_storage

A Flutter plugin to store data in secure storage
https://pub.dartlang.org/packages/flutter_secure_storage
BSD 3-Clause "New" or "Revised" License
1.13k stars 374 forks source link

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

Open NamanShergill opened 2 years ago

NamanShergill commented 2 years ago

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)
NamanShergill commented 2 years ago

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

NamanShergill commented 2 years ago

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?

vlkonoshenko commented 2 years ago

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

NamanShergill commented 2 years ago

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

5.0.2, and yes, it still happens.

vlkonoshenko commented 2 years ago

@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?

NamanShergill commented 2 years ago

@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.

peterhijma commented 2 years ago

Got the same error today.

amitBlueVine commented 2 years ago

Got the same error today

MiroLiebschner commented 2 years ago

Same error today. @NamanShergill there a reason you use _storage.deleteAll() instead of just deleting the key with _storage..delete(key: "accessToken")? I am a bit hesitant to delete all data in secure storage

NamanShergill commented 2 years ago

Same error today. @NamanShergill there a reason you use _storage.deleteAll() instead of just deleting the key with _storage..delete(key: "accessToken")? I am a bit hesitant to delete all data in secure storage

No specific reason, I am only storing an access token in it so both would be the same for me.

However, is there any point in not deleting everything if the plugin will throw an exception every time you try accessing that data?

jeff-odopass commented 2 years ago

I'm also experiencing the same issue, happened for 12 of my end-users in production. I noticed that most of these issues were with Samsung phones, specially the ones named 'SM-G...'. It appeared only for Android 11 & 12 for now. Same stacktrace as mentioned above, let me know if you need anything.

jtmuller5 commented 2 years ago

This is happening on my Samsung S22. Adding allowBackup and fullBackupContent did not fix the issue.

SithumDilanga commented 2 years ago

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?

this solved my issue

senenpalanca97 commented 2 years ago

Got the same error today.

juliansteenbakker commented 2 years ago

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

I will look into this, thanks

tal-nir commented 2 years ago

Got the same error today.

EhabSalah commented 2 years ago

Any Updates ????

fionues commented 2 years ago

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.

AlgoritmoDelCambio commented 2 years ago

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 😭

georgiosd commented 2 years ago

So there's no workaround for this? 😭

royvangeel commented 2 years ago

Any updates on this?

Yongle-Fu commented 2 years ago

Samsung

same issue in Xiaomi 2201122C, X-Client-Version: Android 12 / SDK 31

gerritwitkamp commented 2 years ago

Any progress on this?

ghost commented 2 years ago

Just to make sure, its safer not to use flutter_secure_storage for android unless this problem is fixed, right?

jfahrenkrug commented 2 years ago

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

DamienMrtl commented 2 years ago

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)

Fixed it for me. Thanks :D

simplenotezy commented 2 years ago

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 commented 2 years ago

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

justincbeck commented 1 year ago

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?

Why not use a different SecureStorage (one that uses encryptedSharedPreferences: true,) for the deleteAll() call? That way you won't crash the app completely and you won't be faced with the performance issues I described above. For now, this is what I'm going to do.

AhmedKhattab95 commented 1 year ago

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?

kmoreau commented 1 year ago

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?

Same question here, can we activate 'EncryptedSharedPreferences' without any risk for users ? thx

AristideVB commented 1 year ago

Still having this issue on v8.0.0

mirkomartino commented 1 year ago

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" ...>
bahman2000 commented 8 months ago

Still an issue.

flutter_secure_storage 9.0.0 in Android 9.

acheronian commented 7 months ago

Got the issue randomly on Android 14 devices, LogCat shows following error in production app:

[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: PlatformException(Exception encountered, read, javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT
    at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
    at com.android.org.conscrypt.OpenSSLEvpCipher.doFinalInternal(OpenSSLEvpCipher.java:152)
    at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:374)
    at javax.crypto.Cipher.doFinal(Cipher.java:2056)
    at w6.h.b(Unknown Source:35)
    at v6.a.c(Unknown Source:11)
    at v6.a.k(Unknown Source:17)
    at v6.e$b.run(Unknown Source:233)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.os.HandlerThread.run(HandlerThread.java:67)
, null)
#0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:607)
#1      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:167)
joabsantos commented 6 months ago

Got same today

flutter_secure_storage: ^8.1.0

Nithsua commented 5 months ago

flutter_secure_storage: ^9.0.0, still happening. Seems like this should be a hight priority issue and the solution is reinstalling the app itself. It's such a bad UX.

Any update on the status of this...

Nithsua commented 5 months ago

Also curious does it happen on other operations like write() for anyone?

nemanja-nikolic-goldbear commented 5 months ago

I am still having issues on Samsung S23 Ultra and Samsung A54 5G mostly, users have to login couple times a day because app looses token from the storage (unable to read the token). Using version ^8.1.0 . And using crashlytics I have proved that randomly device can not read the storage by key, just return null, but key is in the storage. Same app version, 95% of the users have never complained.

brandon-watkins-avcrm commented 2 months ago

Any news on this? I am seeing it happen today on Android 9

juliansteenbakker commented 2 months ago

This issue is probably caused by the JetSec Crypto library. I am trying to rewrite this library because it is deprecated, and progress will be tracked in #769 . It would be great if someone could test this implementation when the first beta will be released.

bahadirarslan commented 3 weeks ago

I am still having issues on Samsung S23 Ultra and Samsung A54 5G mostly, users have to login couple times a day because app looses token from the storage (unable to read the token). Using version ^8.1.0 . And using crashlytics I have proved that randomly device can not read the storage by key, just return null, but key is in the storage. Same app version, 95% of the users have never complained.

Same situation, instead of only Samsung devices MI devices have also problems with this library. They can not read token from storage.