重要なデータを保存するためにキーチェーンを使用します。iOS keychain - errSecItemNotFound with iOS 9.2 beta 3
iOS 9.2ベータ3以降、以前のバージョンのiOS(iOS 9.1など)から作成した機密データは取得できません。 SecItemCopyMatchingを使用しているときにエラーerrSecItemNotFoundがあります。 iOS 9.1(iOS 9.2 beta 2、iOS 7.x/8.x/9.0も問題ありません)
非常に奇妙な:私のソースコードは存在しなければ新しい機密データを作成するので、私は新しい機密データを持っていますが、私がiOS 9.1に戻った場合、古い機密データ、そしてその裏のiOS 9.2ベータ3に行くときに... 私はまったく同じクエリを使用しているため、それはキーチェーンが重複しているようだ...ここ
は、機密データを追加するための私のコードです:
NSMutableDictionary *symmetricKeyAttr = [NSMutableDictionary dictionary];
[symmetricKeyAttr setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];
[symmetricKeyAttr setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[symmetricKeyAttr setObject:[NSNumber numberWithUnsignedInt:CSSM_ALGID_AES] forKey:(__bridge id)kSecAttrKeyType];
[symmetricKeyAttr setObject:[NSNumber numberWithUnsignedInt:(unsigned int)(kChosenCipherKeySize << 3)] forKey:(__bridge id)kSecAttrKeySizeInBits];
[symmetricKeyAttr setObject:[NSNumber numberWithUnsignedInt:(unsigned int)(kChosenCipherKeySize << 3)]
forKey:(__bridge id)kSecAttrEffectiveKeySize];
[symmetricKeyAttr setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecAttrCanEncrypt];
[symmetricKeyAttr setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecAttrCanDecrypt];
[symmetricKeyAttr setObject:(id)kCFBooleanFalse forKey:(__bridge id)kSecAttrCanDerive];
[symmetricKeyAttr setObject:(id)kCFBooleanFalse forKey:(__bridge id)kSecAttrCanSign];
[symmetricKeyAttr setObject:(id)kCFBooleanFalse forKey:(__bridge id)kSecAttrCanVerify];
[symmetricKeyAttr setObject:(id)kCFBooleanFalse forKey:(__bridge id)kSecAttrCanWrap];
[symmetricKeyAttr setObject:(id)kCFBooleanFalse forKey:(__bridge id)kSecAttrCanUnwrap];
[symmetricKeyAttr setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
[symmetricKeyAttr setObject:applicationTag forKey:(__bridge id)kSecAttrApplicationTag];
[symmetricKeyAttr setObject:sensitiveData forKey:(__bridge id)kSecValueData];
OSStatus sanityCheck = SecItemAdd((__bridge CFDictionaryRef) symmetricKeyAttr, NULL);
ここでは機密データを取得するためのコードです:
NSMutableDictionary * querySymmetricKey = [NSMutableDictionary dictionary];
[querySymmetricKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[querySymmetricKey setObject:[NSNumber numberWithUnsignedInt:CSSM_ALGID_AES] forKey:(__bridge id)kSecAttrKeyType];
[querySymmetricKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnData];
[querySymmetricKey setObject:applicationTag forKey:(__bridge id)kSecAttrApplicationTag];
[querySymmetricKey setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
CFDataRef symmetricKeyDataRef = NULL;
OSStatus sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)querySymmetricKey, (CFTypeRef *)&symmetricKeyDataRef);
:
- sensitiveDataがストアに機密データ(例えば< ac746cc2 80f72948 59d0d8b7 a5de4bad 5d9e9eb1 a400fba3 c85f3f2e 675d58bf>)
- accessGroupチーム識別子の連結であり、アプリケーション
- 識別子(例えばXXXXXXXXXX.com.toto.tata)applicationTagは、賢明なデータ(例えばに関するタグ ある< 746F746F>)
見所:
- 問題は、唯一の64ビットデバイスと32ビットデバイスに問題が発生しません。
- CSSM_ALGID_AESをCSSM_ALGID_NONEに置き換えると問題が解決します(iOS 9.1で作成されたデータはiOS 9.2のベータ3で適切に取得できます)。しかし、CSSM_ALGID_AESを使用してiOS 9.1で作成したデータを読み取る必要があるため、
- 問題はkSecAttrAccessGroupとは関係ありません。このプロパティを削除しても問題は残ります。
- アップルのサンプル(https://developer.apple.com/library/ios/samplecode/CryptoExercise)で問題を「再現」しました。このサンプルでは、kSecAttrAccessGroupではなくCSSM_ALGID_AESも使用しています。 64ビットデバイスを使用する:iOS 9.2 beta 3では、iOS 9.1(< bdd17fe1 f515e2b1 14de7c43 c4cb6a70>)で作成されたキーが見つかりましたが、別の値(< 73b205e2 46230f69 fa0f347c 2958e6b1>)があります。 32ビットデバイスを使用する:キーは、iOS 9.1とiOS 9.2ベータ3
ノートの間で同じである:
- 私はすでにアップルのフォーラムが、アップルからの応答なしに、この質問を投稿しました... https://forums.developer.apple.com/message/87080
- iOS 9.1と9.2 beta 3の間で、IPSWファイルを使用してバックアップの復元を行わずに切り替えますが、バックアップの復元を行うことで同じ問題が発生します。