keychain的功能简介

来源:互联网 发布:java 列出n之前的质数 编辑:程序博客网 时间:2024/05/01 17:58

keychain(钥匙串) 提供了一种安全的保存私密信息(密码,序列号,证书等)的方式。即使重新安装程序保存过的密码也不会丢失。

keychain可以安全的记录用户的密码,其中keychain保存的密码文件都是经过加密的,通常情况下即使直接打开这个加密文件也获取不到keychain中的密码。

Apple提供了使用keychain的API,详细可见:Keychain Services Reference

 

IOS中keychain与NSUserdefaults相比

NSUserdefaults适用于保存轻量级的数据,加载NSUserdefaults中的数据相对要快一些,数据以明文的形式保存在plist文件,所以不适合用来保存密码。文件的位置是Library/Application Support/iPhone Simulator/模拟器版本/Applications/应用对应的数字/Library/Preference/.plist文件

keychain采用的是将数据加密之后再保存到本地的,这样对数据而言有更高的安全性,适合保存密码之类的数据。数据保存的目录是Library/Application Support/iPhone Simulator/模拟器版本/Library/Keychains/

使用方法:

在工程中导入Security.framework

代码:

CHKeychain.h

   1:  #import <Foundation/Foundation.h>  
   2:  #import <Security/Security.h>  
   3:    
   4:    
   5:  @interface CHKeychain : NSObject  
   6:    
   7:  + (void)save:(NSString *)service data:(id)data;  
   8:  + (id)load:(NSString *)service;  
   9:  + (void)delete:(NSString *)service;  
  10:    
  11:    
  12:  @end  

CHKeychain.m

   1:  #import "CHKeychain.h"  
   2:    
   3:  @implementation CHKeychain  
   4:  + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {  
   5:      return [NSMutableDictionary dictionaryWithObjectsAndKeys:  
   6:              (id)kSecClassGenericPassword,(id)kSecClass,  
   7:              service, (id)kSecAttrService,  
   8:              service, (id)kSecAttrAccount,  
   9:              (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,  
  10:              nil];  
  11:  }  
  12:    
  13:  + (void)save:(NSString *)service data:(id)data {  
  14:      //Get search dictionary  
  15:      NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
  16:      //Delete old item before add new item  
  17:      SecItemDelete((CFDictionaryRef)keychainQuery);  
  18:      //Add new object to search dictionary(Attention:the data format)  
  19:      [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];  
  20:      //Add item to keychain with the search dictionary  
  21:      SecItemAdd((CFDictionaryRef)keychainQuery, NULL);  
  22:  }  
  23:    
  24:  + (id)load:(NSString *)service {  
  25:      id ret = nil;  
  26:      NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
  27:      //Configure the search setting  
  28:      //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue  
  29:      [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];  
  30:      [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];  
  31:      CFDataRef keyData = NULL;  
  32:      if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {  
  33:          @try {  
  34:              ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData];  
  35:          } @catch (NSException *e) {  
  36:              NSLog(@"Unarchive of %@ failed: %@", service, e);  
  37:          } @finally {  
  38:  }  
  39:      }  
  40:      if (keyData)   
  41:      CFRelease(keyData);  
  42:      return ret;  
  43:  }  
  44:    
  45:  + (void)delete:(NSString *)service {  
  46:      NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
  47:      SecItemDelete((CFDictionaryRef)keychainQuery);  
  48:  }  
  49:    
  50:    
  51:  @end

 

1.定义几个字符串用来做key:

   1:  NSString * const KEY_USERNAME_PASSWORD = @"com.company.app.usernamepassword";  
   2:  NSString * const KEY_USERNAME = @"com.company.app.username";  
   3:  NSString * const KEY_PASSWORD = @"com.company.app.password";

 

2.  把用户名和密码存入keychain:

   1:  NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary];  
   2:  [usernamepasswordKVPairs setObject:txtfldUsername.text forKey:KEY_USERNAME];  
   3:  [usernamepasswordKVPairs setObject:txtfldPassword.text forKey:KEY_PASSWORD];  
   4:  [CHKeychain save:KEY_USERNAME_PASSWORD data:usernamepasswordKVPairs]; 

3.  从keychain中取出用户名和密码:

   1:  NSMutableDictionary *usernamepasswordKVPairs = (NSMutableDictionary *)[CHKeychain load:KEY_USERNAME_PASSWORD];  
   2:  txtfldUsername.text = [usernamepasswordKVPairs objectForKey:KEY_USERNAME];  
   3:  txtfldPassword.text = [usernamepasswordKVPairs objectForKey:KEY_PASSWORD];  

 

4. 删除一个keychain item:

   1:  [CHKeychain delete:KEY_USERNAME_PASSWORD];