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

2016-04-06  本文已影响391人  lichengjin

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中,以增加安全性。

上一篇下一篇

猜你喜欢

热点阅读