您的位置:首页 > 移动开发 > IOS开发

iOS开发——keychain的使用

2015-10-26 11:28 721 查看
通常情况下,我们用NSUserDefaults存储数据信息,但是对于一些私密信息,比如密码、证书等等,就需要使用更为安全的keychain了。keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在。

使用苹果官方发布的KeychainItemWrapper或者SFHFKeychainUtils很方便,后来看到 iphone使用keychain来存取用户名和密码 一文,觉得对了解keychain有很大的帮助,于是ARC控也尝试了一把。

需要导入Security.framework 

@implementation WQKeyChain

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {

    

    return [NSMutableDictionary
dictionaryWithObjectsAndKeys:

            

            (__bridge_transfer
id)kSecClassGenericPassword,(__bridge_transfer
id)kSecClass,

            
            service, (__bridge_transfer
id)kSecAttrService,

            
            service, (__bridge_transfer
id)kSecAttrAccount,

            

            (__bridge_transfer
id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer
id)kSecAttrAccessible,

            
           
nil];

    
}

+ (void)save:(NSString *)service data:(id)data {

    

    //Get search dictionary

    
   
NSMutableDictionary *keychainQuery = [self
getKeychainQuery:service];

    

    //Delete old item before add new item

    
   
SecItemDelete((__bridge_retained
CFDictionaryRef)keychainQuery);

    

    //Add new object to search dictionary(Attention:the data format)

    

    [keychainQuery setObject:[NSKeyedArchiver
archivedDataWithRootObject:data] forKey:(__bridge_transfer
id)kSecValueData];

    

    //Add item to keychain with the search dictionary

    
   
SecItemAdd((__bridge_retained
CFDictionaryRef)keychainQuery,
NULL);

    
}

+ (id)load:(NSString *)service {

    
   
id ret = nil;

    
   
NSMutableDictionary *keychainQuery = [self
getKeychainQuery:service];

    

    //Configure the search setting

    
    [keychainQuery
setObject:(id)kCFBooleanTrue
forKey:(__bridge_transfer
id)kSecReturnData];

    

    [keychainQuery setObject:(__bridge_transfer
id)kSecMatchLimitOne
forKey:(__bridge_transfer
id)kSecMatchLimit];

    
   
CFDataRef keyData =
NULL;

    
   
if (SecItemCopyMatching((__bridge_retained
CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) ==
noErr) {

        
       
@try {

            
            ret = [NSKeyedUnarchiver
unarchiveObjectWithData:(__bridge_transfer
NSData *)keyData];

            
        }
@catch (NSException *e) {

            

            NSLog(@"Unarchive of %@ failed: %@", service, e);

            
        }
@finally {

            
        }

        
    }

    
   
return ret;

    
}

+ (void)delete:(NSString *)service {

    
   
NSMutableDictionary *keychainQuery = [self
getKeychainQuery:service];

    
   
SecItemDelete((__bridge_retained
CFDictionaryRef)keychainQuery);

    
}

@end
@interface WQUserDataManager :
NSObject

/**

 

 *    @brief   
存储密码

 

 *

 

 *    @param     password    
密码内容

 

 */

+(void)savePassWord:(NSString *)password;

/**

 

 *    @brief   
读取密码

 

 *

 

 *    @return   
密码内容

 

 */

+(id)readPassWord;

/**

 

 *    @brief   
删除密码数据

 

 */

+(void)deletePassWord;

@end

#import "WQUserDataManager.h"

@implementation WQUserDataManager

static NSString *
const KEY_IN_KEYCHAIN =
@"com.wuqian.app.allinfo";

static NSString *
const KEY_PASSWORD =
@"com.wuqian.app.password";

+(void)savePassWord:(NSString *)password

{

    

    NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary
dictionary];

    
    [usernamepasswordKVPairs
setObject:password
forKey:KEY_PASSWORD];

    
    [WQKeyChain save:KEY_IN_KEYCHAIN data:usernamepasswordKVPairs];

    
}

+(id)readPassWord

{

    
   
NSMutableDictionary *usernamepasswordKVPair = (NSMutableDictionary *)[WQKeyChain load:KEY_IN_KEYCHAIN];

    
   
return [usernamepasswordKVPair
objectForKey:KEY_PASSWORD];

    
}

+(void)deletePassWord

{

    
    [WQKeyChain delete:KEY_IN_KEYCHAIN];

    
}

@end

实现一个简单的界面,把设定的密码存起来,然后立即读取显示出来看看效果

-(IBAction)btnAciton:(id)sender

{

    [WQUserDataManager savePassWord:self.textfield.text];

    self.label.text = [WQUserDataManager readPassWord];

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: