iOS 使用KeyChain存储数据

来源:互联网 发布:工作计划表软件 编辑:程序博客网 时间:2024/05/18 01:52

  这周学习了KeyChain。通常情况下,我们用NSUserDefaults存储数据信息,但是对于一些私密信息,比如密码、证书等等,就需要使用更为安全的keychain了。keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在。

   KeyChain的4种操作 增(SecItemAdd),删(SecItemDelete),改(SecItemUpdate),查(SecItemCopyMatching)。

   还有就是Accessible的几个种类

//keychain项保护等级列表  kSecAttrAccessibleWhenUnlocked                          //keychain项受到保护,只有在设备未被锁定时才可以访问  kSecAttrAccessibleAfterFirstUnlock                      //keychain项受到保护,直到设备启动并且用户第一次输入密码  kSecAttrAccessibleAlways                                //keychain未受保护,任何时候都可以访问 (Default)  kSecAttrAccessibleWhenUnlockedThisDeviceOnly            //keychain项受到保护,只有在设备未被锁定时才可以访问,而且不可以转移到其他设备  kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly        //keychain项受到保护,直到设备启动并且用户第一次输入密码,而且不可以转移到其他设备  kSecAttrAccessibleAlwaysThisDeviceOnly                  //keychain未受保护,任何时候都可以访问,但是不能转移到其他设备

  关于kSecClass的几个种类

CFTypeRef kSecClassGenericPassword            //一般密码      CFTypeRef kSecClassInternetPassword           //网络密码      CFTypeRef kSecClassCertificate                //证书      CFTypeRef kSecClassKey                        //密钥      CFTypeRef kSecClassIdentity                   //身份证书(带私钥的证书)
弹出框的提示信息的属性:kSecUseOperationPrompt 

还有好多属性 如果不明白的话可以 看这篇文章
  如果还是不明白 可以看官方文档
  最后一段使用的 代码, 美女念茜的,  一个官方的例子 KeyChain和TouchID的结合   下载链接

    @implementation WQKeyChain        + (NSMutableDictionary *)getKeychainQuery:(NSString *)service {        return [NSMutableDictionary dictionaryWithObjectsAndKeys:                (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,                service, (__bridge_transfer id)kSecAttrService,                service, (__bridge_transfer id)kSecAttrAccount,                (__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible,                nil nil];        }                + (void)save:(NSString *)service data:(id)data {            //Get search dictionary            NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];            //Delete old item before add new item            SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);            //Add new object to search dictionary(Attention:the data format)            [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];            //Add item to keychain with the search dictionary            SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);        }                + (id)load:(NSString *)service {            id ret = nil;            NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];            //Configure the search setting            [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];            [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];            CFDataRef keyData = NULL;            if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {                @try {                    ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];                } @catch (NSException *e) {                    NSLog(@"Unarchive of %@ failed: %@", service, e);                } @finally {                }            }            return ret;        }                + (void)delete:(NSString *)service {            NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];            SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);        }        @end    </span>



0 0