iOS钥匙串 - 带有iOS 9.2 beta 3的errSecItemNotFound

mdu*_*mdu 5 keychain ios ios9

我使用钥匙串存储敏感数据.

从iOS 9.2 beta 3开始,我无法检索从以前版本的iOS(例如iOS 9.1)创建的敏感数据.使用SecItemCopyMatching时,我有一个错误errSecItemNotFound.iOS 9.1没有问题(iOS 9.2 beta 2也没有iOS 7.x/8.x/9.0).

很奇怪:如果不存在,我的源代码会创建一个新的敏感数据,所以对于iOS 9.2 beta 3,我有一个新的敏感数据,但如果我切换回iOS 9.1,我会检索旧的敏感数据,依此类推当回到iOS 9.2 beta 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);
Run Code Online (Sandbox Code Playgroud)

以下是获取敏感数据的代码:

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);
Run Code Online (Sandbox Code Playgroud)

哪里:

  • sensitiveData是要存储的敏感数据(例如<ac746cc2 80f72948 59d0d8b7 a5de4bad 5d9e9eb1 a400fba3 c85f3f2e 675d58bf>)
  • accessGroup是团队标识符和应用程序的串联
  • 标识符(例如XXXXXXXXXX.com.toto.tata)applicationTag是与敏感数据相关的标记(例如<746F746F>)

附加要点:

  • 只有64位设备才会出现此问题,32位设备没有问题.
  • 用CSSM_ALGID_NONE替换CSSM_ALGID_AES解决了这个问题(即使用iOS 9.2 beta 3可以正确检索用iOS 9.1创建的数据),但这是不可接受的,因为我必须能够使用CSSM_ALGID_AES读取在iOS 9.1上创建的数据.
  • 该问题与kSecAttrAccessGroup无关:当我删除此属性时,我仍然遇到问题.
  • 我已经"转载"Apple的样本问题(https://developer.apple.com/library/ios/samplecode/CryptoExercise).此示例也使用CSSM_ALGID_AES而不是kSecAttrAccessGroup.使用64位设备:在iOS 9.2 beta 3中找到使用iOS 9.1(<bdd17fe1 f515e2b1 14de7c43 c4cb6a70>)创建的密钥,但它具有不同的值(<73b205e2 46230f69 fa0f347c 2958e6b1>)!! 使用32位设备:iOS 9.1和iOS 9.2 beta 3之间的密钥相同.

笔记:

  • 我已经在Apple论坛上发布了这个问题,但Apple没有回复... https://forums.developer.apple.com/message/87080
  • 我使用IPSW文件在iOS 9.1和9.2 beta 3之间切换而不进行备份恢复,但我通过备份恢复遇到了同样的问题.

任何的想法?

小智 0

我在iOS9.2官方上有同样的问题,我可以在任何设备上重现这个问题,用iPhone 6、iPhone 5S和iPad Pro进行测试。

在 iPhone 4S 和 iPad mini 上没有问题,我在每台设备上都验证了这一点。