zoukankan      html  css  js  c++  java
  • keychains

    keychain在ios中是保存在sqlite数据库中的。
    这个数据库文件的位置:
    真机:
    /private/var/Keychains/keychain-2.db
    虚拟机:
    /Users/USER-HOME/Library/Developer/CoreSimulator/Devices/26DCA62C-B516-4DEA-A601-5C2D0EA07710/data/Library/Keychains/keychain-2-debug.db
    在虚拟机中,这个数据库考出来就不能读了,很奇怪。


    下面的每一项都代表一张表。每张表的字段是不同的。
    kSecClassGenericPassword   对应的表:genp
    kSecClassInternetPassword  对应的表:inet
    kSecClassCertificate       对应的表:cert
    CFTypeRef kSecClassKey     对应的表:keys
    CFTypeRef kSecClassIdentity 对应的表:没找到,应该是cert和key这两个表联起来用,各放一部分。


    每个表拥有的字段都是以 kSecAttr开头定义的。
    表中有些字段是系统自己维护的,如cdate:创建时间,mdate:修改时间还有创建者等。
    这些字段都指定了数据类型,所以什么字段放什么类型的值都是字段定死的。
    比如,kSecClassGenericPassword下的kSecAttrService就只能保存字符串。


    因为有些字段的值是枚举类型的,比如
    kSecClassInternetPassword下的kSecAttrProtocol字段,就是一个枚举类型,

    所以定义了很多kSecAttrProtocol开头的常量。

    最常用的kSecClassGenericPassword表:genp

    这个表的主键是kSecAttrAccount   和kSecAttrService   ,所以新建一项SecItem时,这两项在已有项中不能重。


    这三个常量都对应表的data字段,但在从数据库取出后,会转为不同的数据类型。
    这个字段是会加密保存的。
    kSecValueData
    kSecValueRef
    kSecValuePersistentRef



    kSecClassGenericPassword item attributes:
            kSecAttrAccessible
            kSecAttrAccessControl
            kSecAttrAccessGroup     对应字段:agrp
            kSecAttrCreationDate    对应字段:cdat 
            kSecAttrModificationDate  对应字段:mdat
            kSecAttrDescription   对应字段:desc
            kSecAttrComment 
            kSecAttrCreator   对应字段:crtr
            kSecAttrType     对应字段:type
            kSecAttrLabel    对应字段:labl
            kSecAttrIsInvisible 对应字段:invi
            kSecAttrIsNegative  对应字段:nega
            kSecAttrAccount   对应字段:acct
            kSecAttrService   对应字段:svce
            kSecAttrGeneric    对应字段:gena

    苹果官方的KeychainItemWrapper库中用的就是kSecClassGenericPassword,但是用错了。这个库太老了,而且很久没更新了,不建议用。
    - (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup;
    把identifier的值设给了kSecAttrGeneric字段,这是错的,因为kSecAttrGeneric不是主键。


    所以下面的代码中,建第二项时会报错,原因就是主键重复了。
     KeychainItemWrapper * keychin1 = [[KeychainItemWrapper alloc]initWithIdentifier:@"pwd1" accessGroup:nil];
     [keychin1 setObject:pwd1 forKey:(__bridge id)kSecValueData];
    //上面的执行后,下面的执行出错:
     KeychainItemWrapper * keychin2 = [[KeychainItemWrapper alloc]initWithIdentifier:@"pwd1" accessGroup:nil];
     [keychin2 setObject:pwd2 forKey:(__bridge id)kSecValueData];


    换成下面的就可以了:
     KeychainItemWrapper * keychin2 = [[KeychainItemWrapper alloc]initWithIdentifier:@"pwd2" accessGroup:nil];
     [keychin2 setObject:pwd2 forKey:(__bridge id)kSecAttrService];

  • 相关阅读:
    .Net操作Sharepoint常用方法(1) 判断List或Library是否存在
    Aspose.Cells读取Excel获取DataTable方法
    Nginx系统学习笔记(1)Say Hello
    老刘Hadoop学习笔记(6)Hadoop 单机模式 伪分布式 完全分布式区别
    老刘Hadoop学习笔记(5)安装JDK
    老刘Hadoop学习笔记(4)JDK和Open JDK区别
    老刘Hadoop学习笔记(3)新建用户及用户组
    老刘Hadoop学习笔记(2)修改虚拟机hostname及hosts文件
    老刘Hadoop学习笔记(1)开始学习
    MySQL中变量为空时不执行where过滤
  • 原文地址:https://www.cnblogs.com/cwy173/p/6362913.html
Copyright © 2011-2022 走看看