iOS密码保存(keychain简单使用)

来源:互联网 发布:人工智能的坏处 编辑:程序博客网 时间:2024/06/06 01:14

iOS中保存密码,如果要追求安全性,那么使用苹果自带的Keychain Services无疑是最佳选择。如果要在程序中使用Keychain Services,首先要添加Security.framework。

Keychain Services提供了一系列api用以存取和更新keychain item:

SecItemAdd(添加)

SecItemUpdate(更新)

SecItemCopyMatching(查找)

SecItemDelete(删除)

这些方法直接使用有点麻烦,需要进行面向对象的封装。我写了一个简单的例子,只是用来保存用户名和密码,以实现记住密码这项功能。

下面贴一部分代码,完整项目下载:https://github.com/tenric/KeyChainDemo

MyKeyChainHelper.h

复制代码
#import <Foundation/Foundation.h>@interface MyKeyChainHelper : NSObject+ (void) saveUserName:(NSString*)userName       userNameService:(NSString*)userNameService              psaaword:(NSString*)pwd       psaawordService:(NSString*)pwdService;+ (void) deleteWithUserNameService:(NSString*)userNameService                    psaawordService:(NSString*)pwdService;+ (NSString*) getUserNameWithService:(NSString*)userNameService;+ (NSString*) getPasswordWithService:(NSString*)pwdService;@end
复制代码

MyKeyChainHelper.m

复制代码
#import "MyKeyChainHelper.h"@implementation MyKeyChainHelper+ (NSMutableDictionary *)getKeyChainQuery:(NSString *)service {      return [NSMutableDictionary dictionaryWithObjectsAndKeys:              (id)kSecClassGenericPassword,(id)kSecClass,              service, (id)kSecAttrService,              service, (id)kSecAttrAccount,              (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,              nil];  }  + (void) saveUserName:(NSString*)userName       userNameService:(NSString*)userNameService              psaaword:(NSString*)pwd       psaawordService:(NSString*)pwdService{    NSMutableDictionary *keychainQuery = [self getKeyChainQuery:userNameService];      SecItemDelete((CFDictionaryRef)keychainQuery);      [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:userName] forKey:(id)kSecValueData];      SecItemAdd((CFDictionaryRef)keychainQuery, NULL);         keychainQuery = [self getKeyChainQuery:pwdService];      SecItemDelete((CFDictionaryRef)keychainQuery);      [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:pwd] forKey:(id)kSecValueData];      SecItemAdd((CFDictionaryRef)keychainQuery, NULL); }+ (void) deleteWithUserNameService:(NSString*)userNameService                    psaawordService:(NSString*)pwdService{    NSMutableDictionary *keychainQuery = [self getKeyChainQuery:userNameService];      SecItemDelete((CFDictionaryRef)keychainQuery);         keychainQuery = [self getKeyChainQuery:pwdService];      SecItemDelete((CFDictionaryRef)keychainQuery); }+ (NSString*) getUserNameWithService:(NSString*)userNameService{    NSString* ret = nil;      NSMutableDictionary *keychainQuery = [self getKeyChainQuery:userNameService];      [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: %@", userNameService, e);          }        @finally         {          }      }      if (keyData)           CFRelease(keyData);      return ret; }+ (NSString*) getPasswordWithService:(NSString*)pwdService{    NSString* ret = nil;      NSMutableDictionary *keychainQuery = [self getKeyChainQuery:pwdService];      [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: %@", pwdService, e);          }        @finally         {          }      }      if (keyData)           CFRelease(keyData);      return ret;}@end
0 0