Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
newbieflutter opened this issue Mar 25, 2023 · 43 comments

Comments

@newbieflutter
Copy link

Hi,
I have upgraded to latest secure storage plugin flutter_secure_storage: 8.0.0.
Below is the complete error.

Exception has occurred.
PlatformException (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:2055)
	at com.it_nomads.fluttersecurestorage.ciphers.StorageCipher18Implementation.decrypt(StorageCipher18Implementation.java:93)
	at com.it_nomads.fluttersecurestorage.FlutterSecureStorage.decodeRawValue(FlutterSecureStorage.java:249)
	at com.it_nomads.fluttersecurestorage.FlutterSecureStorage.read(FlutterSecureStorage.java:69)
	at com.it_nomads.fluttersecurestorage.FlutterSecureStoragePlugin$MethodRunner.run(FlutterSecureStoragePlugin.java:156)
	at android.os.Handler.handleCallback(Handler.java:938)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:236)
	at android.os.HandlerThread.run(HandlerThread.java:67)
, null))

How I initialise and use the flutter secure storage is like below. I keep in in a global file like below. I call the file as authcheck.

import 'package:flutter_secure_storage/flutter_secure_storage.dart';

class AuthCheck{
static const String partnerIdKey = 'partnerIdKey';

static const storage = FlutterSecureStorage(
aOptions: AndroidOptions(
encryptedSharedPreferences: true,
),
);

static Future<String?> getPartnerID() async {
String? partnerIdKey = await storage.read(key: 'partnerIdKey');
return partnerIdKey;
}

static insertDetails(String partnerID) async {

await storage.write(key: partnerIdKey, value: partnerID);

}
}

So which ever page I need to insert or read the value I just insert this page example like this import 'authcheck.dart'; I have been working smoothly in most of my apps but suddenly this errors. IF you see I have also put this option encryptedSharedPreferences: true. What else I could be missing from end ?

@nblum37
Copy link

nblum37 commented Apr 6, 2023

I have a similar issue

@baothgvinamilk
Copy link

Does the author have any solutions? 😸

@CatlinJiao
Copy link

I have a similar issue

@devswingapplicationcom
Copy link

We are seeing the same issue BUT only when building release appbundle and upload to playstore

Not working:

  1. Build aab locally and deploy to Playstore
  2. install from Playstore
  3. --> Boom bad decrypt.
  4. uninstall aab.
  5. download APK from playstore and install --> Boom, bad decrypt

Working:

  1. build apk on dev machine
  2. install apk on phone. - everything works as expected.

?

@wanoghoco
Copy link

have you tried

final FlutterSecureStorage storage = const FlutterSecureStorage(
aOptions: AndroidOptions(
encryptedSharedPreferences: true,
),
);

@biloshkurskyi-ss
Copy link

biloshkurskyi-ss commented May 22, 2023

The same issue was obtained just at the Samsung device (Galaxy S22+). Android 12. Let's look deeper...

Adding of the AndroidOptions helped:
static const storage = FlutterSecureStorage(aOptions: AndroidOptions(encryptedSharedPreferences: true,),;

@llucie
Copy link

llucie commented May 26, 2023

I have exactly the same issue described above, in the same conditions mentionned by @devswingapplicationcom.

To temporarily solve the problem, I clear the secure storage the first time the user installs a new version.
This cannot be done by everyone, but it can help on some cases.
I use both Shared Preferences and Flutter Secure Storage.

I call the following code at startup:

String version = // current version of your app, e.g. 1.0.0
if (sharedPreferences.getString("secureStorageCleared") != version) {
    await flutterSecureStorage.deleteAll();
    await sharedPreferences.setString("secureStorageCleared", version);
}

This will be called only once per new version.

@nick92
Copy link

nick92 commented Jun 20, 2023

Also had this issue, only got this error when built release and installed via play store, not an issue debugging locally, and issue only on Android, not iOS

Clearing the data fixed the issue for me but not a great work-around

@AlexDochioiu
Copy link

AlexDochioiu commented Jul 4, 2023

Had the same issue previously. I am fairly certain that at least some Samsung devices sometimes ignore the following Android flags:

android:allowBackup="false"
android:fullBackupContent="false"

What this means is that some Samsung phones store (locally / or on some google/samsung server) app data when the app is deleted ; and it restores it when the app is re-installed.

However, the padding encryption key DOES NOT leave the device and is deleted when the app is initially deleted.

When the user re-installs the app, a new encryption key is generated/returned. The app will attempt to decrypt the old restored data with the new encryption key, leading to the BadPaddingException.

My recommendation (and what I am doing) is to clear all encrypted data when encountering this exception and start fresh. If you encounter this, the existing encrypted data is almost certainly permanently lost anyways, since the decryption key does not exist anymore.

@jttuboi
Copy link

jttuboi commented Aug 4, 2023

I'm using flutter_secure_storage 8.0.0. Flutter version: 3.10.5.
The line is throwing this error is flutterSecureStorage.read(key: 'key').

I don't know if it can help:

image

Samsung SM-A032M, android 11
image

motorola one vision, android 11
image

moto e22, android 12
image

This is the max I can share about the problem.

@frankmer
Copy link

Had the same issue previously. I am fairly certain that at least some Samsung devices sometimes ignore the following Android flags:

android:allowBackup="false"
android:fullBackupContent="false"

What this means is that some Samsung phones store (locally / or on some google/samsung server) app data when the app is deleted ; and it restores it when the app is re-installed.

However, the padding encryption key DOES NOT leave the device and is deleted when the app is initially deleted.

When the user re-installs the app, a new encryption key is generated/returned. The app will attempt to decrypt the old restored data with the new encryption key, leading to the BadPaddingException.

My recommendation (and what I am doing) is to clear all encrypted data when encountering this exception and start fresh. If you encounter this, the existing encrypted data is almost certainly permanently lost anyways, since the decryption key does not exist anymore.

This problem seems to occur only on SM-G991B (S21) and SM-G996B (S21+).

@LHaanappel
Copy link

Had the same issue previously. I am fairly certain that at least some Samsung devices sometimes ignore the following Android flags:

android:allowBackup="false"
android:fullBackupContent="false"

What this means is that some Samsung phones store (locally / or on some google/samsung server) app data when the app is deleted ; and it restores it when the app is re-installed.

However, the padding encryption key DOES NOT leave the device and is deleted when the app is initially deleted.

When the user re-installs the app, a new encryption key is generated/returned. The app will attempt to decrypt the old restored data with the new encryption key, leading to the BadPaddingException.

My recommendation (and what I am doing) is to clear all encrypted data when encountering this exception and start fresh. If you encounter this, the existing encrypted data is almost certainly permanently lost anyways, since the decryption key does not exist anymore.

I tried this, but the users encounter this exception EVERY time the app is terminated and reopened, not just with a reinstall or a update.
As @frankmer stated it only occurs on the S21 and S21+, and seems to occur since the latest android software update for those devices that was released this october.

@lberaldodev
Copy link

Had the same issue previously. I am fairly certain that at least some Samsung devices sometimes ignore the following Android flags:

android:allowBackup="false"
android:fullBackupContent="false"

What this means is that some Samsung phones store (locally / or on some google/samsung server) app data when the app is deleted ; and it restores it when the app is re-installed.
However, the padding encryption key DOES NOT leave the device and is deleted when the app is initially deleted.
When the user re-installs the app, a new encryption key is generated/returned. The app will attempt to decrypt the old restored data with the new encryption key, leading to the BadPaddingException.
My recommendation (and what I am doing) is to clear all encrypted data when encountering this exception and start fresh. If you encounter this, the existing encrypted data is almost certainly permanently lost anyways, since the decryption key does not exist anymore.

This problem seems to occur only on SM-G991B (S21) and SM-G996B (S21+).

Hey @frankmer, how can i test it? I tried a lot of times but never get success, can't found any log or reference using browser Stack. But a lot of user have been sending a bad review about this issue.

@lberaldodev
Copy link

Has anyone tested using the resetOnError flag (AndroidOptions )? Maybe it can be an internal solution that we don't need to do the try catch in flutter side.

@frankmer
Copy link

frankmer commented Oct 26, 2023

Had the same issue previously. I am fairly certain that at least some Samsung devices sometimes ignore the following Android flags:

android:allowBackup="false"
android:fullBackupContent="false"

What this means is that some Samsung phones store (locally / or on some google/samsung server) app data when the app is deleted ; and it restores it when the app is re-installed.
However, the padding encryption key DOES NOT leave the device and is deleted when the app is initially deleted.
When the user re-installs the app, a new encryption key is generated/returned. The app will attempt to decrypt the old restored data with the new encryption key, leading to the BadPaddingException.
My recommendation (and what I am doing) is to clear all encrypted data when encountering this exception and start fresh. If you encounter this, the existing encrypted data is almost certainly permanently lost anyways, since the decryption key does not exist anymore.

This problem seems to occur only on SM-G991B (S21) and SM-G996B (S21+).

Hey @frankmer, how can i test it? I tried a lot of times but never get success, can't found any log or reference using browser Stack. But a lot of user have been sending a bad review about this issue.

I never tested it on a real device, but I was able to simulate this error by adding an old FlutterSecureStorage.xml to shared_prefs after deleting the appdata. Our customer report only came from these devices, and there were a lot of them. SM-G998B (S21 Ultra) is now also on the list.

@frankmer
Copy link

frankmer commented Oct 26, 2023

I tried this, but the users encounter this exception EVERY time the app is terminated and reopened, not just with a reinstall or a update. As @frankmer stated it only occurs on the S21 and S21+, and seems to occur since the latest android software update for those devices that was released this october.

The real question is whether the error has occurred since or because of the software update. Even if deleting the old data is not a good option. It would be nice to know if this is actually an option or if the error still occurs.

@lberaldodev
Copy link

Had the same issue previously. I am fairly certain that at least some Samsung devices sometimes ignore the following Android flags:

android:allowBackup="false"
android:fullBackupContent="false"

What this means is that some Samsung phones store (locally / or on some google/samsung server) app data when the app is deleted ; and it restores it when the app is re-installed.
However, the padding encryption key DOES NOT leave the device and is deleted when the app is initially deleted.
When the user re-installs the app, a new encryption key is generated/returned. The app will attempt to decrypt the old restored data with the new encryption key, leading to the BadPaddingException.
My recommendation (and what I am doing) is to clear all encrypted data when encountering this exception and start fresh. If you encounter this, the existing encrypted data is almost certainly permanently lost anyways, since the decryption key does not exist anymore.

This problem seems to occur only on SM-G991B (S21) and SM-G996B (S21+).

Hey @frankmer, how can i test it? I tried a lot of times but never get success, can't found any log or reference using browser Stack. But a lot of user have been sending a bad review about this issue.

I never tested it on a real device, but I was able to simulate this error by adding an old FlutterSecureStorage.xml to shared_prefs after deleting the appdata. Our customer report only came from these devices, and there were a lot of them. SM-G998B (S21 Ultra) is now also on the list.

How can I do it? (change the flutterSecureStorage.xml) ? Can you provide a short guide or share any reference? :) Will be very important simulate it here.

@LHaanappel
Copy link

I tried this, but the users encounter this exception EVERY time the app is terminated and reopened, not just with a reinstall or a update. As @frankmer stated it only occurs on the S21 and S21+, and seems to occur since the latest android software update for those devices that was released this october.

The real question is whether the error has occurred since or because of the software update. Even if deleting the old data is not a good option. It would be nice to know if this is actually an option or if the error still occurs.

Using deleteAll and writing something to the secure storage again causes the Exception to be thrown again when our Users are terminating the app and reopening it after. So it seems that the corruption of the data is not a one-time event after the update, but it is completely broken since.

@frankmer
Copy link

frankmer commented Oct 26, 2023

How can I do it? (change the flutterSecureStorage.xml) ? Can you provide a short guide or share any reference? :) Will be very important simulate it here.

I did it via Android Studio. Device Manager > Run Device > Folder Button under Actions. Then use "Save As..." and "Upload..."

Files found in data/data/{appid}/shared_prefs

@lberaldodev
Copy link

How can I do it? (change the flutterSecureStorage.xml) ? Can you provide a short guide or share any reference? :) Will be very important simulate it here.

I did it via Android Studio. Device Manager > Run Device > Folder Button under Actions. Then use "Save As..." and "Upload..."

Files found in data/data/{appid}/shared_prefs

@frankmer thanks for your guide. I did simulate and get the same log error, but the application on device emulator keeps working fine. I saw in the last threads that it crash only in release mode... So its difficult to prevent anything from our side.

@frankmer
Copy link

I tried this, but the users encounter this exception EVERY time the app is terminated and reopened, not just with a reinstall or a update. As @frankmer stated it only occurs on the S21 and S21+, and seems to occur since the latest android software update for those devices that was released this october.

Can anyone test if this error still occurs when the application is uninstalled and then reinstalled? Some customers say this fixes the problem.

@LHaanappel
Copy link

I tried this, but the users encounter this exception EVERY time the app is terminated and reopened, not just with a reinstall or a update. As @frankmer stated it only occurs on the S21 and S21+, and seems to occur since the latest android software update for those devices that was released this october.

Can anyone test if this error still occurs when the application is uninstalled and then reinstalled? Some customers say this fixes the problem.

That is interesting, the first thing we recommended to our customers was to reinstall the app but that didn't seem to help them..
Could it have something to do with android:allowBackup="false" being deprecated from Android 12 and higher?

This is how we have it in our app:

android:allowBackup="false"
android:fullBackupContent="@xml/backup_rules"`

With in the backup_rules:

<full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

This was the solution when we encountered this problem a few years back, see:
#43 (comment)

@frankmer
Copy link

That is interesting, the first thing we recommended to our customers was to reinstall the app but that didn't seem to help them.. Could it have something to do with android:allowBackup="false" being deprecated from Android 12 and higher?

This is how we have it in our app:

android:allowBackup="false"
android:fullBackupContent="@xml/backup_rules"`

With in the backup_rules:

<full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

This was the solution when we encountered this problem a few years back, see: #43 (comment)

The current problem has nothing to do with the old problem from a few years ago. If reinstalling really fixes it, then my guess is that the link between the key and the application itself is broken, and reinstalling the application will reestablish that link. Although reinstalling may cause the other problem if backup is enabled.

@lberaldodev
Copy link

android:allowBackup="false"

I dont think that the changes on android 12 will impact on this error because they are for the d2d backup.

reference

@lberaldodev
Copy link

That is interesting, the first thing we recommended to our customers was to reinstall the app but that didn't seem to help them.. Could it have something to do with android:allowBackup="false" being deprecated from Android 12 and higher?
This is how we have it in our app:

android:allowBackup="false"
android:fullBackupContent="@xml/backup_rules"`

With in the backup_rules:

<full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

This was the solution when we encountered this problem a few years back, see: #43 (comment)

The current problem has nothing to do with the old problem from a few years ago. If reinstalling really fixes it, then my guess is that the link between the key and the application itself is broken, and reinstalling the application will reestablish that link. Although reinstalling may cause the other problem if backup is enabled.

I really think that this is the point. Because here the backup is enabled and the reinstall isnt working. So we are changing to false and we will check in the next release. :)

@LHaanappel
Copy link

That is interesting, the first thing we recommended to our customers was to reinstall the app but that didn't seem to help them.. Could it have something to do with android:allowBackup="false" being deprecated from Android 12 and higher?
This is how we have it in our app:

android:allowBackup="false"
android:fullBackupContent="@xml/backup_rules"`

With in the backup_rules:

<full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

This was the solution when we encountered this problem a few years back, see: #43 (comment)

The current problem has nothing to do with the old problem from a few years ago. If reinstalling really fixes it, then my guess is that the link between the key and the application itself is broken, and reinstalling the application will reestablish that link. Although reinstalling may cause the other problem if backup is enabled.

android:fullBackupContent="false" indeed fixed all our problems, thanks! 😄

@lberaldodev
Copy link

That is interesting, the first thing we recommended to our customers was to reinstall the app but that didn't seem to help them.. Could it have something to do with android:allowBackup="false" being deprecated from Android 12 and higher?
This is how we have it in our app:

android:allowBackup="false"
android:fullBackupContent="@xml/backup_rules"`

With in the backup_rules:

<full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

This was the solution when we encountered this problem a few years back, see: #43 (comment)

The current problem has nothing to do with the old problem from a few years ago. If reinstalling really fixes it, then my guess is that the link between the key and the application itself is broken, and reinstalling the application will reestablish that link. Although reinstalling may cause the other problem if backup is enabled.

android:fullBackupContent="false" indeed fixed all our problems, thanks! 😄

the try catch suggestion was not necessary? :)

@PieterAelse
Copy link
Contributor

Instead of doing

<full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

Shouldn't it be:

For Android up to 11:

<full-backup-content>
    <exclude domain="sharedpref" path="FlutterSecureKeyStorage"/>
    <exclude domain="sharedpref" path="FlutterSecureStorage"/>
</full-backup-content>

For Android 12 and up:

<data-extraction-rules>
    <cloud-backup >
        <exclude domain="sharedpref" path="FlutterSecureStorage"/>
        <exclude domain="sharedpref" path="FlutterSecureKeyStorage"/>
    </cloud-backup>
    <device-transfer>
        <exclude domain="sharedpref" path="FlutterSecureStorage"/>
        <exclude domain="sharedpref" path="FlutterSecureKeyStorage"/>
    </device-transfer>
</data-extraction-rules>

As I see that:

  • Android up-to-11 and Android 12-and-up require different formats of the xml backup file
  • flutter_secure_storage uses two files

@bqubique
Copy link

What worked for me was this:

AndroidManifest.xml

    <application
        ...
        android:fullBackupContent="false"
        android:allowBackup="false"
        android:dataExtractionRules="@xml/data_extraction_rules"
...

And as @PieterAelse pointed out:

<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules>
    <cloud-backup>
        <exclude domain="root" />
        <exclude domain="file" />
        <exclude domain="database" />
        <exclude domain="sharedpref" />
        <exclude domain="external" />
        <exclude domain="sharedpref" path="FlutterSecureStorage"/>
        <exclude domain="sharedpref" path="FlutterSecureKeyStorage"/>
    </cloud-backup>
    <device-transfer>
        <exclude domain="root" />
        <exclude domain="file" />
        <exclude domain="database" />
        <exclude domain="sharedpref" />
        <exclude domain="external" />
        <exclude domain="sharedpref" path="FlutterSecureStorage"/>
        <exclude domain="sharedpref" path="FlutterSecureKeyStorage"/>
    </device-transfer>
</data-extraction-rules>

I'm on flutter_secure_storage: ^9.0.0 and Flutter 3.16.4 if that makes a difference.

@vodemn
Copy link

vodemn commented Jan 26, 2024

@bqubique Do we need to include data-extraction-rules if android:allowBackup="false"? Seems like if backup is not allowed, then these rules won't be even applied.

@bqubique
Copy link

@vodemn I just had a read of this [https://developer.android.com/guide/topics/data/autobackup](Back up user data with Auto Backup), and seems like there's no need for the separate data-extraction-rules file. I can't recall if I tried that, but that should've been the very first thing I would try so I'm guessing I already tried that but it did not work. Our issue wasn't evident on every type of device, my Pixel would work just fine i.e. delete the data after an uninstall, but for some reason Samsung devices had a different way of handling this issue, and in the end what I posted above worked perfectly.

Right now though I have completely replaced flutter_secure_storage with shared_preferenced and encrypt/decrypt data on the fly. I'm sure this is not as safe as flutter_secure_storage but I wanted to have a single point of failure/repository.

@orailnoor
Copy link

resolved flutter_secure_storage: ^9.0.0
const secureStorage = FlutterSecureStorage(
aOptions: AndroidOptions(
encryptedSharedPreferences: true,
));

@echap1
Copy link

echap1 commented Feb 20, 2024

resolved flutter_secure_storage: ^9.0.0 const secureStorage = FlutterSecureStorage( aOptions: AndroidOptions( encryptedSharedPreferences: true, ));

Still experiencing this issue and doing this does not resolve...

@LuuNgocLan
Copy link

LuuNgocLan commented Apr 9, 2024

Hope it can helps you!

I am using flutter_secure_storage: ^8.0.0 and upgrading to ^9.0.0 is not a priority,
I have added to all method read, write,...

aOptions: AndroidOptions(
encryptedSharedPreferences: true,
)

and it works fine until the deleteAll function, it can't completely delete the data, so I force reset the data by flag resetOnError = true this helps the app's data to be consistent and works well with new aOptions settings.

image

image

image

PlatformException(Exception encountered, deleteAll, java.lang.SecurityException: Could not decrypt key. decryption failed at androidx.security.crypto.a.c(Unknown Source:58) at androidx.security.crypto.a.getAll(Unknown Source:49) at androidx.security.crypto.a$b.a(Unknown Source:11) at androidx.security.crypto.a$b.apply(Unknown Source:0) at jd.a.e(Unknown Source:23) at jd.e$b.run(Unknown Source:135) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:226) at android.os.Looper.loop(Looper.java:313) at android.os.HandlerThread.run(HandlerThread.java:67) Caused by: java.security.GeneralSecurityException: decryption failed at la.c$a.b(Unknown Source:136) at androidx.security.crypto.a.c(Unknown Source:13) ... 10 more , null)

@moha-b
Copy link

moha-b commented Jun 29, 2024

Has this been resolved yet? 🥹

@renenucci
Copy link

Still hapening.. any news?

@moha-b
Copy link

moha-b commented Jul 10, 2024

okay that's works for me not sure it works on all devices

1 - clear the cache in the first run

// main.dart
  if (!CachingHelper.instance!.readBoolean(CachingKey.ONBOARDING)) {
    CachingHelper.instance!.clearSecrets();  // <- Here I remove everything at the beginning (there is nothing stored yet)
  }

2 - add this to the mainfist.xml file

 <application
        android:label="Tasker"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
        android:allowBackup="false"
        android:fullBackupContent="false"
    >

3 - Used version

  flutter_secure_storage: ^9.2.2

@barilki
Copy link

barilki commented Jul 22, 2024

Any updates?

@juliansteenbakker
Copy link
Owner

Im closing this as duplicate of #354

@Pulkit0729
Copy link

The reason is clearly because of this. You can try clearing app data and try, it will work.

The same issue was obtained just at the Samsung device (Galaxy S22+). Android 12. Let's look deeper...

Adding of the AndroidOptions helped: static const storage = FlutterSecureStorage(aOptions: AndroidOptions(encryptedSharedPreferences: true,),;

@FadyFayezYounan
Copy link

FadyFayezYounan commented Nov 20, 2024

same issue

1 similar comment
@don-pironet-hatch
Copy link

same issue

@naresh-fluidra
Copy link

same

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests