Work with KeyChain in IOS

来源:互联网 发布:学生作业管理系统源码 编辑:程序博客网 时间:2024/06/07 02:26

What is keychain?
A keychain is an encrypted container that holds passwords for multiple applications and secure services.
We can use keychain to store multiple accounts in sercure FTP servers, AppleShare servers, database servers and secure websites, and so on.
In addition to passwords (I think here passwords mean data), keychains can store cryptographic keys, certifications and (in OS X) test strings (notes).

Keychains are secure storage containers. Both OS X and IOS have keychain.
In OS X, user can lock/unlock a keychain. After unlocking the keychain(should enter passworld), the apps can access to the contents.

In IOS, users are never asked to unlock the keychain. The app can only access its own keychain items. (For the same application, make sure the provisioning file is same, for keychain rights depend on the provisioning file.)

How many keychains do we have?
In OS X, users can create multiple keychains. The default keychain is login keychain, which is unlocked on default.
In IOS, there is only one keychain, can each application can only access to its only items.

Structure of keychain?
keychain ->(contains) keychain item1 -> encrypted data, attributes
               ->                 keychain item2 -> ...
               ->                 ...

Keeping your OS X keychain data SECURE

In OS X, to provide security for the passwords and other valuable secrets stored in your keychain, you should
adopt at least the following measures:
● Set your keychain to lock itself when not in use: in the Keychain Access utility, choose Edit > Change
Settings for Keychain, and check both Lock checkboxes.
● Use a different password for your keychain than your login password: In Keychain Access utility, choose
Edit > Change Password to change your keychain's password. Click the lock icon in the Change Password
dialog to get the password assistant, which tells you how secure your password is and can suggest
passwords. Be sure to pick one you can remember—don't write it down anywhere

 

iPhone keychain backups
When a user backs up iPhone data, the keychain data is backed up, and the data in the keychain remain encrypted in the backup. The keychain password(Every application has different password) is not include in the backup. 

Read/Update keyitems in IOS

读取keychain中的内容:

+ (NSString*)getPasswordWithAccount:(NSString*)account service:(NSString*)service{if (service == nil || account == nil) {return nil;}NSMutableDictionary* query = [NSMutableDictionary dictionary];[query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];[query setObject:(id)service forKey:(id)kSecAttrService];[query setObject:(id)account forKey:(id)kSecAttrAccount];[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];NSString* password = nil;NSData* passwordData = nil;OSStatus err = SecItemCopyMatching((CFDictionaryRef)query,   (CFTypeRef*)&passwordData);if (err == noErr) {password = [[[NSString alloc] initWithData:passwordData                                          encoding:NSUTF8StringEncoding] autorelease];[passwordData release];} else if(err == errSecItemNotFound) {// do nothing[passwordData release];} else {NSLog(@"%s|SecItemCopyMatching: error(%ld)", __PRETTY_FUNCTION__, err);}return password;}

更新keychain item:

+ (BOOL)updatePassword:(NSString*)password account:(NSString*)account service:(NSString*)service{BOOL result = NO;NSMutableDictionary* attributes = nil;NSMutableDictionary* query = [NSMutableDictionary dictionary];NSData* passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];[query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];[query setObject:(id)service forKey:(id)kSecAttrService];[query setObject:(id)account forKey:(id)kSecAttrAccount];OSStatus err = SecItemCopyMatching((CFDictionaryRef)query, NULL);if (err == noErr) {// update itemattributes = [NSMutableDictionary dictionary];[attributes setObject:passwordData forKey:(id)kSecValueData];[attributes setObject:[NSDate date] forKey:(id)kSecAttrModificationDate];err = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)attributes);if (err == noErr) {result = YES;} else {NSLog(@"%s|SecItemUpdate: error(%ld)", __PRETTY_FUNCTION__, err);}} else if (err == errSecItemNotFound) {// add new itemattributes = [NSMutableDictionary dictionary];[attributes setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];[attributes setObject:(id)service forKey:(id)kSecAttrService];[attributes setObject:(id)account forKey:(id)kSecAttrAccount];[attributes setObject:passwordData forKey:(id)kSecValueData];[attributes setObject:[NSDate date] forKey:(id)kSecAttrCreationDate];[attributes setObject:[NSDate date] forKey:(id)kSecAttrModificationDate];err = SecItemAdd((CFDictionaryRef)attributes, NULL);if (err == noErr) {result = YES;} else {NSLog(@"%s|SecItemAdd: error(%ld)", __PRETTY_FUNCTION__, err);}} else {NSLog(@"%s|SecItemCopyMatching: error(%ld)", __PRETTY_FUNCTION__, err);}return result;}

删除keychain item:

+ (BOOL)deletePasswordWithAccount:(NSString*)account service:(NSString*)service{BOOL result = NO;NSMutableDictionary* query = [NSMutableDictionary dictionary];[query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];[query setObject:(id)service forKey:(id)kSecAttrService];[query setObject:(id)account forKey:(id)kSecAttrAccount];OSStatus err = SecItemDelete((CFDictionaryRef)query);if (err == noErr) {result = YES;} else {NSLog(@"%s|SecItemDelete: error(%ld)", __PRETTY_FUNCTION__, err);}return result;}
以上。


Ref:
https://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/keychainServConcepts.pdf

原创粉丝点击