flutter_secure_storage icon indicating copy to clipboard operation
flutter_secure_storage copied to clipboard

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

Open namanshergill opened this issue 3 years ago • 42 comments

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 avatar Jan 15 '22 03:01 namanshergill

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

namanshergill avatar Jan 15 '22 03:01 namanshergill

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?

namanshergill avatar Jan 15 '22 03:01 namanshergill

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

vlkonoshenko avatar Feb 02 '22 12:02 vlkonoshenko

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

5.0.2, and yes, it still happens.

namanshergill avatar Feb 02 '22 12:02 namanshergill

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

vlkonoshenko avatar Feb 02 '22 12:02 vlkonoshenko

@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 avatar Feb 02 '22 16:02 namanshergill

Got the same error today.

peterhijma avatar Feb 15 '22 10:02 peterhijma

Got the same error today

amitBlueVine avatar Feb 23 '22 07:02 amitBlueVine

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

MiroLiebschner avatar Mar 02 '22 10:03 MiroLiebschner

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?

namanshergill avatar Mar 02 '22 13:03 namanshergill

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.

jeff-odopass avatar Mar 03 '22 16:03 jeff-odopass

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

jtmuller5 avatar Mar 09 '22 15:03 jtmuller5

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

SithumDilanga avatar Mar 12 '22 19:03 SithumDilanga

Got the same error today.

senenpalanca97 avatar Mar 14 '22 13:03 senenpalanca97

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

I will look into this, thanks

juliansteenbakker avatar Mar 14 '22 15:03 juliansteenbakker

Got the same error today.

tal-nir avatar Mar 29 '22 14:03 tal-nir

Any Updates ????

EhabSalah avatar Apr 03 '22 12:04 EhabSalah

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.

fionues avatar Apr 04 '22 14:04 fionues

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 😭

AlgoritmoDelCambio avatar May 06 '22 14:05 AlgoritmoDelCambio

So there's no workaround for this? 😭

georgiosd avatar May 12 '22 05:05 georgiosd

Any updates on this?

royvangeel avatar May 16 '22 06:05 royvangeel

Samsung

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

Yongle-Fu avatar May 18 '22 06:05 Yongle-Fu

Any progress on this?

gerritwitkamp avatar Jun 22 '22 06:06 gerritwitkamp

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

iriguchi-reno avatar Jun 29 '22 08:06 iriguchi-reno

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

jfahrenkrug avatar Jun 29 '22 18:06 jfahrenkrug

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

DamienMrtl avatar Jul 01 '22 19:07 DamienMrtl

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

simplenotezy avatar Jul 02 '22 11:07 simplenotezy

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

namanshergill avatar Jul 02 '22 12:07 namanshergill

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.

justincbeck avatar Jan 26 '23 22:01 justincbeck

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?

AhmedKhattab95 avatar Feb 23 '23 15:02 AhmedKhattab95