保存iOS密碼(簡單使用keychain)
2023-05-22
在iOS中保存密碼,如果你想追求安全,那么使用蘋果自己的Keychain。 毫無疑問,Services是最好的選擇。若要使用Keychainn系統(tǒng) Services,首先要添加Security.framework。
Keychain Services為存儲和更新keychainninn帶來了一系列api。 item:
SecItemAdd(添加)
SecItemUpdate(更新)
SecItemCopyMatching(查找)
SecItemDelete(刪掉)
直接使用這些方法有點麻煩,需要對對象進行包裝。我寫了一個典型的例子,只是用來存儲賬戶密碼,以實現(xiàn)記憶密碼的功能。
以下是一些代碼,完整的項目下載: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
本文僅代表作者觀點,版權(quán)歸原創(chuàng)者所有,如需轉(zhuǎn)載請在文中注明來源及作者名字。
免責(zé)聲明:本文系轉(zhuǎn)載編輯文章,僅作分享之用。如分享內(nèi)容、圖片侵犯到您的版權(quán)或非授權(quán)發(fā)布,請及時與我們聯(lián)系進行審核處理或刪除,您可以發(fā)送材料至郵箱:service@tojoy.com


