iOS keychain 卸載後依然存在的持久化存儲

// 封裝
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SecItemHelper : NSObject
+ (void)saveFromName:(NSString *)name data:(id)data;
+ (id)loadFromName:(NSString *)name;
+ (void)deletedataFromName:(NSString *)name;
@end

NS_ASSUME_NONNULL_END



#import "SecItemHelper.h"

@implementation SecItemHelper
+ (void)saveFromName:(NSString *)name data:(id)data
{
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:name];
    // 清空
    SecItemDelete((CFDictionaryRef)keychainQuery);
    // 賦值
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
    // 添加
    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}

+ (id)loadFromName:(NSString *)name
{
    id ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:name];
    [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:(__bridge NSData *)keyData];
        }
        @catch (NSException *e)
        {
            NSLog(@"Unarchive of %@ failed: %@", name, e);
        }
        @finally
        {
            
        }
    }
    if (keyData)
    {
        CFRelease(keyData);
    }
    return ret;
}

+ (void)deletedataFromName:(NSString *)name
{
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:name];
    SecItemDelete((CFDictionaryRef)keychainQuery);
}

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)name
{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [dic setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
    [dic setValue:name forKey:(id)kSecAttrAccount];
    [dic setValue:name forKey:(id)kSecAttrService];
    // 解鎖後可以的安全蛇者
    [dic setValue:(id)kSecAttrAccessibleAfterFirstUnlock forKey:(id)kSecAttrAccessible];
    return dic;
}

@end
// 調用
#import "ViewController.h"
#import "SecItemHelper.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    
    NSString *name = NSStringFromClass(ViewController.class);
    
    NSMutableDictionary *dic =[NSMutableDictionary dictionary];
    [dic setValue:@"xiaoming" forKey:@"user"];
    [dic setValue:@"123456" forKey:@"password"];
    
    [SecItemHelper saveFromName:name data:dic];
    
  id data =  [SecItemHelper loadFromName:name];
    
    NSLog(@"%@",data);
    
//    [SecItemHelper deletedata:name];
//    id data2 =  [SecItemHelper load:name];
//    NSLog(@"%@",data2);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
// 譯文

kSecAttrAccessibleWhenUnlocked
當解鎖時,kSec具有可訪問性  推薦使用 iCloud同步
kSecAttrAccessibleAfterFirstUnlock
第一次解鎖後可訪問kSec     iCloud同步
kSecAttrAccessibleAlways
一直訪問 不建議使用      iCloud同步
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
當密碼僅設置此設備時,kSec Attr可訪問  iCloud不同步
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
只有在解鎖此設備時才能訪問kSec Attr  iCloud不同步
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
只有在首次解鎖此設備後才能訪問kSec Attr  iCloud不同步
kSecAttrAccessibleAlwaysThisDeviceOnly
kSec Attr始終只能訪問此設備 iCloud不同步

kSecClassInternetPassword
表示Internet密碼項的值。

kSecClassCertificate
表示證書項的值。

kSecClassKey
表示加密密鑰項的值。

kSecClassIdentity
表示標識項的值。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章