Open yourior opened 1 month ago
@yourior I’m seeing the same error here, not sure what it’s related to just yet. It used to work just fine, so I’m currently investigating.
@KasperTidemann it works by initializing it using the default method
final storage = const FlutterSecureStorage();
then call the option using the function
storage.write(key: Keyname,value: value,iOptions: _getIOSOptions(),aOptions: _getAndroidOptions());
I also had the same error. Please help me!
This is beacuse of that changes: https://github.com/mogol/flutter_secure_storage/commit/1364ad9937bcd7834142aff967fc40d288ea8ea8
This is breaking change. Should be WRITTEN DOWN IN CHANGELOG. From this commit, accessibility now is part of query path to keychain.
use readAll
to get value from Storage. (await secureStorage.readAll())[StorageConstants.secureStorageKey];
This fixes the issue
None of previous suggestion does works.
Seems, that some keychain access keys or ciphers or appleid-related stuff is changed in latest ios update. So keychain data, written previously by this or another application with the same attributes became unaccessible. Solvable by adding custom attribute (accountName
for example):
iosOptions.accountName='something-different-from-previous'
Options can be passed in constructor. No need for write
, read
, delete
special options. In case of further ios keychain critical updates accountName
should be changed again.
I had also same error faced. Kindly provide the solution ![Uploading Screenshot 2024-05-17 at 12.10.55 PM.png…]()
I have faced this error. Yesterday work fine but today has error show.
PlatformException(Unexpected security result code, Code: -25300, Message: The specified item could not be found in the keychain., -25300, null), stackTrace: #0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:648:7)
Hi @bierbaumtim.
Your code here has a breaking change, which is not described in changelogs and it is unclear how to get around it or fix the code. Please give a couple of comments, because right now the only option is to go back to the version is set in pubspec.yaml flutter_secure_storage: 9.0.0
is there any promotion?
I have released v9.2.1 which should fix this, however there are atill some reports that i is not fully functional just yet, so i'm going to investigate further
None of previous suggestion does works.
Seems, that some keychain access keys or ciphers or appleid-related stuff is changed in latest ios update. So keychain data, written previously by this or another application with the same attributes became unaccessible. Solvable by adding custom attribute (
accountName
for example):iosOptions.accountName='something-different-from-previous'
Options can be passed in constructor. No need for
write
,read
,delete
special options. In case of further ios keychain critical updatesaccountName
should be changed again.
@PROGrand Do you have a link to more info about the iOS keychain breaking changes? And what iOS versions are affected?
Some of my users are being automaticallty logged out because the keychain data is no longer accessible. If I use a custom accountName for the ios options, will I be able to access the old keychain data? Or does this change apply only from now on when writing new data?
When you say "written previously by this or another application", do you mean that in the case of an iOS device that has 2 random apps installed that use the flutter_secure_storage with the default ios options, one of the app's use of the plugin makes the other's app's data unaccessible? Or am I understanding this wrong? By default, the accountName used by flutter_secure_storage is identical in all apps that use it.
still getting this error on write with v9.2.2:
PlatformException (PlatformException(Unexpected security result code, Code: -25299, Message: Das angegebene Objekt befindet sich bereits im Schlüsselbund., -25299, null))
translation of this german string is "The specified item already exists in the keychain"
changing the IOSOptions accountName to something unique did not help
this seems only to happen when the same key is written quickly multiple times, I do not see the error when setting a breakpoint at the write call
Any updates to this? Upgrading from 9.0.0 to 9.2.2 produces this error and yes, I can add a new accountName, but that basically resets all the saved key/values and every user in our app gets logged out.
That because key was saved using different options.
In my case, I started using first_unlock
, but keys were saved without it and I use read/delete(key, iOptions: IOSOptions()) then saves with new options.
https://github.com/mogol/flutter_secure_storage/compare/v9.2.1...v9.2.2
Starting with v9.2.2, kSecAttrAccessible
has been changed to a non-nil value when reading/writing. So (for example) a value written to KeyChain with accessibility
as nil
in v9.0.0, will be read in v9.2.2 with accessibility
as kSecAttrAccessibleWhenUnlocked
.
If accessibility
is used to check for SecItemCopyMatching
, would it not be necessary to check both the nil
case and the accessibility
case with the write
function?
I have confirmed that KeychainAccessibility.unlocked
is set as the default for IOSOptions
. It's not nil when saving...
I'm trying to find a way to fix this issue but without having to force all my users to sign out. Adding IOSOptions with an accountName seems to solve the original issue but it can no longer access the existing values so the users are forced to sign out. Is it possible somehow to be able to read the existing values if I change iOSOptions?
Did you also notice that setting a breakpoint, similar to introducing a delay between write calls, does not trigger the exception? I only see it for multiple quick calls to write
Could we consider changing the containsKey
implementation back from SecItemCopyMatching
to a determination by the read
method?
If the error code is correct, the write
method uses SecItemAdd
in the case where SecItemUpdate
is used. The difference between containsKey
and read
is “whether it uses the second argument of SecItemCopyMatching
” and read
appears to be better suited for this determination.
I'll just leave this here
it works...
const FlutterSecureStorage secureStorage = FlutterSecureStorage(
iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock),
);
String? secureKey;
try {
await secureStorage.waitingAvailability();
secureKey = await secureStorage.read(key: _secureKeyName);
// try to read with old options
if (secureKey == null && Platform.isIOS) {
secureKey = await secureStorage.read(key: _secureKeyName, iOptions: const IOSOptions());
// rewrite with new options
if (secureKey != null) {
Logger(loggerSecurity).info('Rewrite secure key with new options');
await secureStorage.delete(key: _secureKeyName, iOptions: const IOSOptions());
await secureStorage.write(key: _secureKeyName, value: secureKey);
}
}
} catch (e, t) {
Logger(loggerSecurity).severe('Failed to read secure key from storage', e, t);
}
@justprodev Thank you for your solution. I failed to find secureStorage.waitingAvailability();
method and initiated the same migration just after initialization (if data is already available) step for all keys iterating one by one with similar code. And call the same migration process as a reaction for onCupertinoProtectedDataAvailabilityChanged
listener.
This is beacuse of that changes: 1364ad9
This is breaking change. Should be WRITTEN DOWN IN CHANGELOG. From this commit, accessibility now is part of query path to keychain.
This is the only part of this discussion that is important and should be heeded by the authors / publishers of FlutterSecureStorage
.
The change to Accessibility in this commit now DISALLOWS any calls to READ without an Accessibility set. This flag is largely unnecessary on read as it potentially results in a narrow scope in the search of the keychain for a stored key.
Furthermore, you cannot return to the previous query. It is no longer possible to read without passing the accessibility flag. This thread is a result of this breakage - you cannot read in the same manner as before.
AppleOptions.accessibility should be made nullable for some queries, even if it's required for writes.
The values written to Keychain using flutter_secure_storage have had kSecAttrAccessible
set at write
since v6.1.0 (from the version rewritten to swift as far as we can tell).
I am not familiar with objective-c, so I can't say that there is nothing wrong with the code before that.
What I am wondering is if there are "values stored with accessibility of nil". As far as I can see, that problem does not appear to occur in the values stored by flutter_secure_storage.
Also, I think https://github.com/mogol/flutter_secure_storage/pull/719 has more information on the problem that occurs when Accessibility is set to nil on read.
Any new,?
here is my initialize code
the error showed when i want to write a value into a key
storage.write(key: Keyname,value: value);
is this a bug or is there a setting that i need to set for IOS? because this works in android