【iOS】Keychain 钥匙串

钥匙串,实际上是一个加密后的数据库,如下图所示。
即使吧App删除,钥匙串里面的数据也不会丢失。

0304151a-f84e-44b1-8632-6698ec59854b.png

数据都是以 Item 的形式来存储的,每个 Item 由一个加密后的 Data 数据,还有一系列用来描述该 Item 属性的 Attributes 组成。
由于是数据库,关键方法只有四种,增删改查,对应的是

  • SecItemAdd
  • SecItemDelete
  • SecItemUpdate
  • SecItemCopyMatching

下面简单讲述一下使用方法

SecItemAdd

    CFTypeRef result;
    NSDictionary *query = @{
        // 一个典型的新增方法的参数,包含三个部分
        // 1.kSecClass key,它用来指定新增对象的类型
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2.若干项属性 key,例如 kSecAttrAccount,kSecAttrLabel 等,用来描述新增对象的属性
        (NSString *)kSecAttrAccount: @"uniqueID",
        // 3.kSecValueData key,用来设置新增对象保存的数据
        (NSString *)kSecValueData: [@"token" dataUsingEncoding:NSUTF8StringEncoding],
        // 可选
        // 如果需要获取新增的 Item 对象的属性,需要如下属性,
        (NSString *)kSecReturnData: (NSNumber *)kCFBooleanTrue,
        (NSString *)kSecReturnAttributes: (NSNumber *)kCFBooleanTrue,
    };
    OSStatus status = SecItemAdd((CFDictionaryRef)query, &result);
    if (result == errSecSuccess) {
        // 新增成功
        NSDictionary *itemInfo = (__bridge NSDictionary *)result;
        NSLog(@"info: %@", itemInfo);
    } else {
        // 其他错误
    }

result类型判断方式

kSecReturnData kSecReturnAttributes result
true true NSDictionary(包含属性与数据)
true false NSData(只有数据)
false true NSDictionary(只包含属性)
false false null

SecItemDelete

    NSDictionary *query = @{
        // 一个典型的删除方法的参数,包含两个部分
        // 1、kSecClass key,它用来指定删除对象的类型,必填。
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2、若干项属性 key,可选。
        // 例如 kSecAttrAccount,kSecAttrLabel 等,用来设置删除对象的范围
        // 默认情况下,符合条件的全部 Item 都会被删除
        (NSString *)kSecAttrAccount: @"uniqueID",
    };
    OSStatus status = SecItemDelete((CFDictionaryRef)query);
    if (result == errSecSuccess) {
        // 删除成功
    } else {
        // 其他错误
    }

SecItemUpdate

    // 1、找出需要更新属性的 Item
    // 参数格式与 SecItemCopyMatching 方法中的参数格式相同
    NSDictionary *query = @{
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        (NSString *)kSecAttrAccount: @"uniqueID",
    };
    
    // 2、需要更新的属性
    // 若干项属性 key
    NSDictionary *update = @{
        (NSString *)kSecAttrAccount: @"another uniqueID",
        (NSString *)kSecValueData: @"another value",
    };

    OSStatus status = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)update);

    if (result == errSecSuccess) {
        // 更新成功
    } else {
        // 其他错误
    }

SecItemDelete

    NSDictionary *query = @{
        // 一个典型的删除方法的参数,包含两个部分
        // 1、kSecClass key,它用来指定删除对象的类型,必填。
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2、若干项属性 key,可选。
        // 例如 kSecAttrAccount,kSecAttrLabel 等,用来设置删除对象的范围
        // 默认情况下,符合条件的全部 Item 都会被删除
        (NSString *)kSecAttrAccount: @"uniqueID",
    };
    OSStatus status = SecItemDelete((CFDictionaryRef)query);
    if (result == errSecSuccess) {
        // 删除成功
    } else {
        // 其他错误
    }

SecItemCopyMatching

    CFTypeRef result;
    NSDictionary *query = @{
        // 一个典型的搜索方法的参数,包含三个部分
        // 1、kSecClass key(必填),它用来指定搜索对象的类型
        (NSString *)kSecClass: (NSString *)kSecClassGenericPassword,
        // 2、若干项属性 key(可选),例如 kSecAttrAccount,kSecAttrLabel 等,用来描述搜索对象的属性
        (NSString *)kSecAttrAccount: @"uniqueID",
        // 3、搜索属性(可选)
        // 例如 kSecMatchLimit(搜索一个还是多个,影响返回结果类型)
        // kSecMatchCaseInsensitive 是否大小写敏感等
        (NSString *)kSecMatchLimit: (NSString *)kSecMatchLimitAll,
        (NSString *) kSecMatchCaseInsensitive: (NSNumber *) kCFBooleanTrue,
        // (可选)如果需要获取新增的 Item 对象的属性,需要如下属性,
        (NSString *)kSecReturnData: (NSNumber *)kCFBooleanTrue,
        (NSString *)kSecReturnAttributes: (NSNumber *)kCFBooleanTrue,
    };
    OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, &result);
    if (result == errSecSuccess) {
        // 新增成功
        NSDictionary *itemInfo = (__bridge NSDictionary *)result;
        NSLog(@"info: %@", itemInfo);
    } else {
        // 其他错误
    }

result类型判断方式

kSecReturnData kSecReturnAttributes kSecMatchLimit result
true true kSecMatchLimitAll NSDictionary(包含属性与数据)数组
true true kSecMatchLimitOne NSDictionary(包含属性与数据)对象
true false kSecMatchLimitAll NSData(只有数据)数组
true false kSecMatchLimitOne NSData(只有数据)对象
false true kSecMatchLimitAll NSDictionary(只包含属性)数组
false true kSecMatchLimitOne NSDictionary(只包含属性)对象
false false kSecMatchLimitAll 空数组
false false kSecMatchLimitOne null

参考文档
https://developer.apple.com/documentation/security/keychain_services/keychain_items?language=occ
Demo 地址
https://github.com/huangrrui/Key-chain

你可能感兴趣的:(【iOS】Keychain 钥匙串)