美文网首页
iOS开发使用keychain保存用户名及密码

iOS开发使用keychain保存用户名及密码

作者: lichengjin | 来源:发表于2016-04-06 23:54 被阅读391次

    KeyChain是苹果提供的一种安全的保存用户名、密码、证书的方式,将敏感信息保存在keychain中后,这些信息不会随着app的卸载而丢失,除非开发人员在app中手动删除敏感信息,否则,这些信息将会一直保存在keychain中。

    在使用keychain时,我们首先要将security.framework引入到工程中。由于使用时不支持arc,所以我们在arc环境中需要针对相关文件启用mrc模式。

    首先,我们构造一个工具类,通过这个类来操作keychain。

    #import<foundation foundation.h="">

    #import<security security.h="">

    @interfaceKeyChain : NSObject

    // save username and password to keychain

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

    // take out username and passwore from keychain

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

    // delete username and password from keychain

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

    @end

    在实现文件中,我们这样写:

    #import"KeyChain.h"

    @implementationKeyChain

    /**

    *该类需要工作在mrc模式下,acr的项目按照如下步骤操作

    *选中工程->TARGETS->相应的target然后选中右侧的“Build Phases”,向下就找到“Compile Sources”了。然后在相应的文件后面添加:-fno-objc-arc参数

    *

    **/

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

    return[NSMutableDictionary dictionaryWithObjectsAndKeys:

    (id)kSecClassGenericPassword,(id)kSecClass,

    service, (id)kSecAttrService,

    service, (id)kSecAttrAccount,

    (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,

    nil];

    }

    #pragma mark 写入

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

    //Get search dictionary

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    //Delete old item before add new item

    SecItemDelete((CFDictionaryRef)keychainQuery);

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

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

    //Add item to keychain with the search dictionary

    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);

    }

    #pragma mark 读取

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

    id ret = nil;

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    //Configure the search setting

    //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

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

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

    CFDataRef keyData = NULL;

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

    @try{

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

    }@catch(NSException *e) {

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

    }@finally{

    }

    }

    if(keyData)

    CFRelease(keyData);

    returnret;

    }

    #pragma mark 删除

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

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery);

    }

    @end

    修改工程的相关放在在代码注释中已经写清楚了。

    下边是使用这个类

    首先,我们定义几个字符串类型的标识符

    NSString *constKEY_USERNAME_PASSWORD = @"com.company.app.usernamepassword";

    NSString *constKEY_USERNAME = @"com.company.app.username";

    NSString *constKEY_PASSWORD = @"com.company.app.password";

    之后,我们创建一个字典,并将用户名和密码放入字典中

    NSMutableDictionary *userNamePasswordKVPairs = [NSMutableDictionary dictionary];

    [userNamePasswordKVPairs setObject:@"userName"forKey:KEY_USERNAME];

    [userNamePasswordKVPairs setObject:@"password"forKey:KEY_PASSWORD];

    下边引用工具类的各个方法,分别进行用户名和密码的添加、读取、删除操作

    // A、将用户名和密码写入keychain

    [KeyChain save:KEY_USERNAME_PASSWORD data:userNamePasswordKVPairs];

    // B、从keychain中读取用户名和密码

    NSMutableDictionary *readUsernamePassword = (NSMutableDictionary *)[KeyChain load:KEY_USERNAME_PASSWORD];

    NSString *userName = [readUsernamePassword objectForKey:KEY_USERNAME];

    NSString *password = [readUsernamePassword objectForKey:KEY_PASSWORD];

    NSLog(@"username = %@", userName);

    NSLog(@"password = %@", password);

    // C、将用户名和密码从keychain中删除

    [KeyChain delete:KEY_USERNAME_PASSWORD];

    keychain的用法还有很多,我们在这里只是简单的将用户名和密码保存在keychain,而不是数据库或nsuserdefaults中,以增加安全性。

    相关文章

      网友评论

          本文标题:iOS开发使用keychain保存用户名及密码

          本文链接:https://www.haomeiwen.com/subject/stpmlttx.html