其他分享
首页 > 其他分享> > iOS keychain 卸载后依然存在的持久化存储

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
表示标识项的值。

 

标签:keychain,name,iOS,keychainQuery,NSString,卸载,forKey,dic,id
来源: https://blog.csdn.net/saw471/article/details/99569655