Created
February 21, 2017 19:25
-
-
Save Raztor0/34ad0e23a410c33526c9fa1b6e8d281c to your computer and use it in GitHub Desktop.
iOS10.3 beta2 Keychain Autodelete Workaround
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (BOOL)saveToKeychain { | |
NSData *passwordData = [@"myPassword" dataUsingEncoding:NSUTF8StringEncoding]; | |
/* Try to save to the keychain */ | |
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3]; | |
[dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; | |
[dictionary setObject:@"myService" forKey:(__bridge id)kSecAttrService]; | |
[dictionary setObject:@"myAccount" forKey:(__bridge id)kSecAttrAccount]; | |
/* Use the kSecAttrAccessGroupToken access group constant*/ | |
[dictionary setObject:(__bridge NSString * _Nullable)(kSecAttrAccessGroupToken) forKey:(__bridge id)kSecAttrAccessGroup]; | |
[dictionary setObject:passwordData forKey:(__bridge id)kSecValueData]; | |
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL); | |
if (status != errSecSuccess) { | |
NSLog(@"Failed to save to keychain"); | |
return NO; | |
} else { | |
NSLog(@"Successfully saved password to keychain"); | |
return YES; | |
} | |
} | |
- (NSString *)fetchFromKeychain { | |
/* Try to fetch from the keychain */ | |
NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3]; | |
[dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; | |
[dictionary setObject:@"myService" forKey:(__bridge id)kSecAttrService]; | |
[dictionary setObject:@"myAccount" forKey:(__bridge id)kSecAttrAccount]; | |
/* Use the kSecAttrAccessGroupToken access group constant*/ | |
[dictionary setObject:(__bridge NSString * _Nullable)(kSecAttrAccessGroupToken) forKey:(__bridge id)kSecAttrAccessGroup]; | |
[dictionary setObject:@YES forKey:(__bridge id)kSecReturnData]; | |
[dictionary setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; | |
NSString *password; | |
CFTypeRef result = NULL; | |
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dictionary, &result); | |
if (status != errSecSuccess) { | |
NSLog(@"Error fetching from keychain"); | |
} else { | |
NSData *passwordData = (__bridge_transfer NSData *)result; | |
password = [[NSString alloc] initWithData:passwordData encoding:NSUTF8StringEncoding]; | |
NSLog(@"Got password from keychain: %@", password); | |
} | |
return password; | |
} |
Can you confirm keychain will be deleted after app uninstalled in iOS 10.3(14E277) ?
@laoyur It seems as though keychain entries continue to persist after app uninstall.
The behaviour experienced in the iOS 10.3 beta does not seem to have made it into the public releases.
Also, according to this reply: https://forums.developer.apple.com/thread/72271#224455 it seems as though the kSecAttrAccessGroup access group identifier was never meant to be written to from normal apps, only read from. So, this code should no longer be relied on.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Execute -saveToKeychain, delete the app, re-install the app, and then execute -fetchFromKeychain
Keychain data will still be there.
Requires >= iOS 10