• iOS 的keyChain


    说明:

    每一个keyChain的组成如图,整体是一个字典结构.
    1.kSecClass key 定义属于那一种类型的keyChain
    2.不同的类型包含不同的Attributes,这些attributes定义了这个item的具体信息
    3.每个item可以包含一个密码项来存储对应的密码

    使用:
    引入Security包,引入文件 #import <Security/Security.h>

    添加

    - (IBAction)add:(id)sender {
    if (nameField.text.length > 0 && passwordField.text.length > 0) {
    // 一个mutable字典结构存储item信息
    NSMutableDictionary* dic = [NSMutableDictionary dictionary];
    // 确定所属的类class
    [dic setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
    // 设置其他属性attributes
    [dic setObject:nameField.text forKey:(id)kSecAttrAccount];
    // 添加密码 secValue 注意是object 是 NSData
    [dic setObject:[passwordField.text dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
    // SecItemAdd
    OSStatus s = SecItemAdd((CFDictionaryRef)dic, NULL);
    NSLog(@"add : %ld",s);
    }
    }


    查找

    // 查找全部
    - (IBAction)sel:(id)sender {
    NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:kSecClassGenericPassword,kSecClass,
    kSecMatchLimitAll,kSecMatchLimit,
    kCFBooleanTrue,kSecReturnAttributes,nil];
    CFTypeRef result = nil;
    OSStatus s = SecItemCopyMatching((CFDictionaryRef)query, &result);
    NSLog(@"se;ect all : %ld",s);
    NSLog(@"%@",result);
    }

    // 按名称查找
    - (IBAction)sname:(id)sender {
    if (nameField.text.length >0) {
    // 查找条件:1.class 2.attributes 3.search option
    NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:kSecClassGenericPassword,kSecClass,
    nameField.text,kSecAttrAccount,
    kCFBooleanTrue,kSecReturnAttributes,nil];
    CFTypeRef result = nil;
    // 先找到一个item
    OSStatus s = SecItemCopyMatching((CFDictionaryRef)query, &result);
    NSLog(@"select name : %ld",s); // errSecItemNotFound 就是找不到
    NSLog(@"%@",result);
    if (s == noErr) {
    // 继续查找item的secValue
    NSMutableDictionary* dic = [NSMutableDictionary dictionaryWithDictionary:result];
    // 存储格式
    [dic setObject:(id)kCFBooleanTrue forKey:kSecReturnData];
    // 确定class
    [dic setObject:[query objectForKey:kSecClass] forKey:kSecClass];
    NSData* data = nil;
    // 查找secValue
    if (SecItemCopyMatching((CFDictionaryRef)dic, (CFTypeRef*)&data) == noErr) {
    if (data.length)
    NSLog(@"%@",[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
    }
    }
    }
    }

    修改

    - (IBAction)update:(id)sender {
    if (nameField.text.length >0 && passwordField.text.length > 0) {
    // 先查找看看有没有
    NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:kSecClassGenericPassword,kSecClass,
    nameField.text,kSecAttrAccount,
    kCFBooleanTrue,kSecReturnAttributes,nil];

    CFTypeRef result = nil;
    if (SecItemCopyMatching((CFDictionaryRef)query, &result) == noErr)
    {
    // 更新后的数据,基础是搜到的result
    NSMutableDictionary* update = [NSMutableDictionary dictionaryWithDictionary:(NSDictionary*)result];
    // 修改要跟新的项 注意先加后删的class项
    [update setObject:[query objectForKey:kSecClass] forKey:kSecClass];
    [update setObject:[passwordField.text dataUsingEncoding:NSUTF8StringEncoding] forKey:kSecValueData];
    [update removeObjectForKey:kSecClass];
    #if TARGET_IPHONE_SIMULATOR
    // 模拟器的都有个默认的组“test”,删了,不然会出错
    [update removeObjectForKey:(id)kSecAttrAccessGroup];
    #endif
    // 得到要修改的item,根据result,但要添加class
    NSMutableDictionary* updateItem = [NSMutableDictionary dictionaryWithDictionary:result];
    [updateItem setObject:[query objectForKey:(id)kSecClass] forKey:(id)kSecClass];
    // SecItemUpdate
    OSStatus status = SecItemUpdate((CFDictionaryRef)updateItem, (CFDictionaryRef)update);
    NSLog(@"update:%ld",status);

    删除

    - (IBAction)del:(id)sender {
    if (nameField.text.length >0) {
    // 删除的条件
    NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:kSecClassGenericPassword,kSecClass,
    nameField.text,kSecAttrAccount,nil];
    // SecItemDelete
    OSStatus status = SecItemDelete((CFDictionaryRef)query);
    NSLog(@"delete:%ld",status); // // errSecItemNotFound 就是没有
    }
    }

    注意:

    1.区别(标识)一个item要用kSecAttrAccount和kSecAttrService

  • 相关阅读:
    分数的表示和运算
    用户管理
    DML,DDL
    索引
    sql语句执行顺序
    伪劣
    序列
    视图
    完整性约束
    ASP.NET MVC学习笔记(二)登陆验证
  • 原文地址:https://www.cnblogs.com/v2m_/p/2325782.html
Copyright © 2020-2023  润新知