Work with KeyChain in IOS

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 item		
		attributes = [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 item
		attributes = [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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值