保存iOS密码(简单使用keychain)
2023-05-22
在iOS中保存密码,如果你想追求安全,那么使用苹果自己的Keychain。 毫无疑问,Services是最好的选择。若要使用Keychainn系统 Services,首先要添加Security.framework。
Keychain Services为存储和更新keychainninn带来了一系列api。 item:
SecItemAdd(添加)
SecItemUpdate(更新)
SecItemCopyMatching(查找)
SecItemDelete(删掉)
直接使用这些方法有点麻烦,需要对对象进行包装。我写了一个典型的例子,只是用来存储账户密码,以实现记忆密码的功能。
以下是一些代码,完整的项目下载:https://github.com/tenric/KeyChainDemo
MyKeyChainHelper.h
#import
@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
本文仅代表作者观点,版权归原创者所有,如需转载请在文中注明来源及作者名字。
免责声明:本文系转载编辑文章,仅作分享之用。如分享内容、图片侵犯到您的版权或非授权发布,请及时与我们联系进行审核处理或删除,您可以发送材料至邮箱:service@tojoy.com