My understanding of the iOS keychain is that is insecure on jailbroken devices.
I was wondering if one stores a value in the keychain using kSecAccessControlTouchIDAny
as it's used in this example from Apple, if there is an extra level of protection, even on jailbroken devices?
Relevant excerpt of example where text is stored into the keychain:
- (void)addTouchIDItemAsync {
CFErrorRef error = NULL;
// Should be the secret invalidated when passcode is removed? If not then use kSecAttrAccessibleWhenUnlocked
SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecAccessControlTouchIDAny, &error);
if (sacObject == NULL || error != NULL) {
NSString *errorString = [NSString stringWithFormat:@"SecItemAdd can't create sacObject: %@", error];
self.textView.text = [self.textView.text stringByAppendingString:errorString];
return;
}
/*
We want the operation to fail if there is an item which needs authentication so we will use
`kSecUseNoAuthenticationUI`.
*/
NSData *secretPasswordTextData = [@"SECRET_PASSWORD_TEXT" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *attributes = @{
(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
(__bridge id)kSecAttrService: @"SampleService",
(__bridge id)kSecValueData: secretPasswordTextData,
(__bridge id)kSecUseNoAuthenticationUI: @YES,
(__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject
};
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
NSString *message = [NSString stringWithFormat:@"SecItemAdd status: %@", [self keychainErrorToString:status]];
[self printMessage:message inTextView:self.textView];
});
}