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

时间:2015-11-13 13:20:57

标签: ios ios9 keychain

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

自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);

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

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

补充要点:

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

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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

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