美文网首页
vicki753's iOS 基础--KeyChain

vicki753's iOS 基础--KeyChain

作者: vicki753 | 来源:发表于2017-11-13 13:36 被阅读6次

    参考地址:

    使用NSUserDefault是不安全的,因为是存储在沙盒中的,实际上是plist文件键值存储,并且最大的问题是存在与沙盒中,这就对安全性埋下了隐患。

    KeyChain 服务存储,Keychain保存的数据不仅仅是加密过的,而且由于Keychain是存在与沙盒之外的,当应用删除之后,app 存储的数据并没有被删掉,第二次安装时只要读取Keychain里的数据,即可得到以前存储的信息。(比如配音秀,之前第一次安装的时候,我点击了不再显示***,然后变换了布局,后来卸载了之后再次安装,嗯,我还真的就再也不能看到之前的了,话说回来,这样真的符合用户交互么?你也不清楚用户想的啥啊~~)其实我觉得它这种做法,就好像手机链接WIFI 输入密码后,苹果电脑就可以直接连接不需要再输入密码了,虽然实现的方式不一样,但也的确是一种提供用户方便的一种措施。

    Keychain使用场景:

    存储隐私信息

    iOS系统中,最常用的就是存储用户密码

    数据共享

    如果我们有多个 app,它们之间需要共享一些数据,以提供更好的用户体验,那么使用Keychain群组可以实现。但前提是同一个公司的产品才能共享,比如:com.hxyy.test1和com.hyyy.test2两个同一个公司下的不同产品之前可以实现数据共享。

    设备唯一标示存储

    在iOS中,为了在苹果的打压下获取唯一标示符,开发者们也是想尽了办法,目前最好的方式就是获取IDFV,并将其存储到Keychain中,IDFV是设备区别应用提供商的,一般来说可以作为应用唯一标示符,但是IDFV缺陷就是当设备删除了该所有应用提供商的app之后,IDFV值会发生变化,所以IDFV+Keychain的组合目前被经常用到,来替代UDID的作用,特别是加上Keychain的共享服务,可以使应用提供商下的所有app下获取的 IDFV都不会发生变化,这一服务可以说是目前最佳的识别用户的办法。

    推荐的库:HYKeychainHelper库

    下面我们来应用一下,如何使用Keychain

    first 需要打开target - Capabilities - Keychain Sharing 点击打开为ON;

    打开之后会自动创建Entitlement文件。也就是说,bundle Identifier、 Keychain Sharing 的Keychain Groups、 Entitlements 文件的Keychain Access Groups的第一个元素,

    //

    //  KeychainStore.m

    //  KeychainDemo

    //

    //  Created by vicki753-mac on 13/11/2017.

    //  Copyright © 2017 zhengyi. All rights reserved.

    //

    #import "KeychainStore.h"

    @implementation KeychainStore

    +(NSMutableDictionary *)getKeychainQuery:(NSString *)service{

    return [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword, (id)kSecClass, service, (id)kSecAttrAccount, (id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible, nil];

    }

    +(void)save:(NSString *)service data:(id)data{

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery); // 删除之前的

    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData]; //用键值对 归档存储

    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);//添加现在的

    }

    +(id)load:(NSString *)service{

    id ret = nil;

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    [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: %@", service, e);

    }@finally {

    }

    }

    if (keyData)

    CFRelease(keyData);

    return ret;

    }

    +(void)deleteKeyData:(NSString *)service{

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];

    SecItemDelete((CFDictionaryRef)keychainQuery);

    }

    @end

    相关文章

      网友评论

          本文标题:vicki753's iOS 基础--KeyChain

          本文链接:https://www.haomeiwen.com/subject/osjbmxtx.html