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: Code: -25308. Help me! #727

Open
gamestap99 opened this issue May 27, 2024 · 22 comments
Open

PlatformException: Code: -25308. Help me! #727

gamestap99 opened this issue May 27, 2024 · 22 comments

Comments

@gamestap99
Copy link

On a beautiful day, I received this token, and it seems that it caused my app to crash. To be more precise, I tried to catch the error, so it didn't take the main key, causing the session to log out. I am using it to encrypt the Hive NoSQL database.
Screenshot 2024-05-27 at 19 21 09

my code using it

 // Create key and encryption
    FlutterSecureStorage secureStorage = const FlutterSecureStorage();
    String? secureStorageKey;
    late List<int> encryptionKey;
    String storeKey = AppConfig.storeKey(isDev: F.appFlavor == Flavor.beta);

    /** @see: https://github.com/mogol/flutter_secure_storage/issues/84*/
    try {
      secureStorageKey = await secureStorage.read(key: storeKey);

      Helpers.dump('secureStorageKey value: $secureStorageKey', line: true);
    } catch (ex, stackTrace) {
      Helpers.reportSentry(ex, stackTrace);

      await secureStorage.delete(key: storeKey);
    }

    if ((secureStorageKey?.isEmpty ?? true)) {
      await secureStorage.delete(key: storeKey);

      var key = Hive.generateSecureKey();

      Helpers.dump('Before Write Key value: $key', line: true);
      Helpers.dump('Before Write secureStorageKey value: ${base64UrlEncode(key)}', line: true);

      await secureStorage.write(
        key: storeKey,
        value: base64UrlEncode(key),
      );

      Helpers.dump('Write success key: $key', line: true);

      encryptionKey = key;
    }else{
      secureStorageKey = await secureStorage.read(key: storeKey);
      encryptionKey = base64Url.decode(secureStorageKey ?? '');
    }


    Helpers.dump('Encryption key: $encryptionKey', line: true);

    //Open Boxes
    await Hive.openBox<UserHiveModel>(UserHiveModel.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
    await Hive.openBox<SettingHiveModel>(SettingHiveModel.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
    await Hive.openBox<GeotrackHiveModel>(GeotrackHiveModel.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
    await Hive.openBox<MAccessTokenHive>(MAccessTokenHive.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
    await Hive.openBox<ProjectHiveModel>(ProjectHiveModel.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
    await Hive.openBox<ActionPostHiveModel>(ActionPostHiveModel.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
    await Hive.openBox<PostHiveModel>(PostHiveModel.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
    await Hive.openBox<MediaHiveModel>(MediaHiveModel.boxKey, encryptionCipher: HiveAesCipher(encryptionKey));
@techouse
Copy link
Contributor

Error -25308 is errSecInteractionNotAllowed.

You might want to read this post on the Apple Developer Forums.

Can you give us some more context, i.e. the OS, version etc.?

@gamestap99
Copy link
Author

@techouse Oke. Project using :

  • FLutter: 3.22.0
  • flutter_secure_storage: ^9.2.2
  • Device: Iphone 11 Pro(arm64) x IOS(v17.4.1)

@abhinand-kv
Copy link

facing the same issue

flutter version: 3.19.3
flutter_secure_storage: 9.2.2

@techouse
Copy link
Contributor

techouse commented May 28, 2024

@gamestap99 Can you replicate this on a simulator or provide us with some sample code that replicates this error?

Does it work with v9.0.0 using something like this?

dependency_overrides:
  flutter_secure_storage: 9.0.0
  flutter_secure_storage_linux: 1.2.0
  flutter_secure_storage_macos: 3.0.1
  flutter_secure_storage_platform_interface: 1.0.2
  flutter_secure_storage_windows: 3.0.0
  flutter_secure_storage_web:  1.2.0

@germinator1512
Copy link

Facing the Same Issue

FLutter: 3.22.0
flutter_secure_storage: ^9.2.1
Device: Iphone 15 Pro  IOS(v17.4.1)

@starshipcoder
Copy link

Same issue for one customer, bug not always
flutter_secure_storage: 9.2.2
iOS 16.7.8

@koutja
Copy link

koutja commented Jun 4, 2024

Same issue for some customers, bug not always, after read data when device was unlocked
flutter_secure_storage: 9.2.2

iOS 17.5.1 - 43,75 %
iOS 17.4.1- 31,25 %
iOS 16.5 - 25 %

@oleksiyPetlyuk
Copy link

This issue is replicable by reading from a secure storage(keychain) when a device is locked and has a passcode.

It can be fixed with:

final _storageProvider = FlutterSecureStorage(
    iOptions: IOSOptions.defaultOptions.copyWith(
      accessibility: KeychainAccessibility.first_unlock_this_device,
      synchronizable: true,
    ),
  );

Note:
Without providing synchronizable: true it throws the errSecDuplicateItem platform exception for me.

@marcotta
Copy link

marcotta commented Jun 6, 2024

Issue disappeared when I downgraded the library:

dependency_overrides:
  # Downgrade secure storage to 9.0.0 as version 9.2.2 has introduced some crashes on iOS
  # The error description is "Unexpected security result code, Code: -25308"
  flutter_secure_storage: 9.0.0
  flutter_secure_storage_linux: 1.2.0
  flutter_secure_storage_macos: 3.0.1
  flutter_secure_storage_platform_interface: 1.0.2
  flutter_secure_storage_web: 1.1.2
  flutter_secure_storage_windows: 3.0.0

@Reprevise
Copy link

This issue is replicable by reading from a secure storage(keychain) when a device is locked and has a passcode.

It can be fixed with:

final _storageProvider = FlutterSecureStorage(
    iOptions: IOSOptions.defaultOptions.copyWith(
      accessibility: KeychainAccessibility.first_unlock_this_device,
      synchronizable: true,
    ),
  );

Note: Without providing synchronizable: true it throws the errSecDuplicateItem platform exception for me.

What are the consequences of doing this?

@oleksiyPetlyuk
Copy link

This issue is replicable by reading from a secure storage(keychain) when a device is locked and has a passcode.
It can be fixed with:

final _storageProvider = FlutterSecureStorage(
    iOptions: IOSOptions.defaultOptions.copyWith(
      accessibility: KeychainAccessibility.first_unlock_this_device,
      synchronizable: true,
    ),
  );

Note: Without providing synchronizable: true it throws the errSecDuplicateItem platform exception for me.

What are the consequences of doing this?

https://developer.apple.com/documentation/security/ksecattraccessibleafterfirstunlock

@DmitryGaimaldinov
Copy link

@mogol, please, can you explain why this happens and can it be fixed by someone?

@revtut
Copy link

revtut commented Sep 19, 2024

We are also getting that crash after upgrading to the v9.2.2 version.
Screenshot 2024-09-19 at 09 04 39

@amrLLSE
Copy link

amrLLSE commented Sep 22, 2024

Facing same issue on latest version.

@bbeckley
Copy link

Facing same issue as well on latest version for some iOS devices with the options fix set.

IOSOptions _getIOSOptions() => const IOSOptions( accessibility: KeychainAccessibility.first_unlock, synchronizable: true, accountName: 'myapp_prefs', );

await _secureStorage.write(key: newItem.key.name, value: newItem.value, aOptions: _getAndroidOptions(), iOptions: _getIOSOptions());

@Tom3652
Copy link

Tom3652 commented Oct 20, 2024

Having the same issue with this initialization but only in release mode in my live app :

 final FlutterSecureStorage _secureStorage = const FlutterSecureStorage(
      aOptions: AndroidOptions(
        encryptedSharedPreferences: true,
      ),
      iOptions: IOSOptions(synchronizable: false)
);

@jostney
Copy link

jostney commented Oct 28, 2024

I changed my usage from

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

to

final _storage = const FlutterSecureStorage(
  aOptions: AndroidOptions(encryptedSharedPreferences: true),
  iOptions: IOSOptions(
    accessibility: KeychainAccessibility.first_unlock_this_device,
    synchronizable: true,
  ),
);

Seems the problem didn't happen but behaved values aren't stored anymore before!

@btrautmann
Copy link

Seems the problem didn't happen but behaved values aren't stored anymore before!

When changing the settings, you need to "migrate" values from the previous settings. I described this in a similar issue.

@jostney
Copy link

jostney commented Oct 28, 2024

Seems the problem didn't happen but behaved values aren't stored anymore before!

When changing the settings, you need to "migrate" values from the previous settings. I described this in a similar issue.

I've just reviewed your metod, it simply uses secure storage first, then uses legacy (shared prefs imho) if secure storage fails. This means same values are stored (must be stored) in secure storage and legacy options both, otherwise this fallback does not work.

In my scenario,

  • App is terminated and device is locked.
  • App receives video call on lock screen and user accepts it.
  • App starts and gets user credentials from secure storage. -----> Here booms

To make work your scenario i would be storing those credentials in "legacy" option too :/

@btrautmann
Copy link

I've just reviewed your metod, it simply uses secure storage first, then uses legacy (shared prefs imho) if secure storage fails. This means same values are stored (must be stored) in secure storage and legacy options both, otherwise this fallback does not work.

No, it's using secure storage in both cases. "Legacy" refers to the secure storage being created/accessed with the old settings. Here's the associated code:

Screenshot 2024-10-28 at 16 57 52

@jostney
Copy link

jostney commented Oct 28, 2024

Yes, my mistake. Both storages are indeed FlutterSecureStorage.

Based on your latest post, it looks like _legacyStorage is the one I’ve already been using, and it’s throwing the 25308 exception.

I also tried _storage (as I mentioned in my first post), but it returns empty for all my keys.

To sum up, using _storage first and getting an empty result, then trying _legacyStorage and getting the 25308 exception, doesn't add up. How would this resolve the issue?

@btrautmann
Copy link

Yes, my mistake. Both storages are indeed FlutterSecureStorage.

Based on your latest post, it looks like _legacyStorage is the one I’ve already been using, and it’s throwing the 25308 exception.

I also tried _storage (as I mentioned in my first post), but it returns empty for all my keys.

To sum up, using _storage first and getting an empty result, then trying _legacyStorage and getting the 25308 exception, doesn't add up. How would this resolve the issue?

In my case, if the app was restarted, the storage was accessible again...It was reading from the background that was messing things up. If in your case the "legacy" storage is fully borked and you can no longer read from it, migration may not be possible.

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