Keychain

1,612 阅读5分钟

keychain 的结构

一个 keychain 结构的 Item 由三部分组成:

  1. Class
  2. Atrribute
  3. SecValue

在对 keychain 进行操作时,需要通过 Dictionary 来指定这三部分,来确定具体操作的 keychain。

下面分别来介绍这三部分:

Class

Class 为 keychain 的类型。使用 kSecClass 作为 key,来指定 Class 的类型。

kSecClass 对应的 value 有五个值,分别为:

  • kSecClassGenericPassword:通用密码
  • kSecClassInternetPassword:互联网密码
  • kSecClassCertificate:证书
  • kSecClassKey:密钥
  • kSecClassIdentity:身份证书(带私钥的证书)

Atrribute

不同类型的 Keychain 包含不同的 Attribute,这些 Attributes 定义了这个 Keychain 的具体信息。

Atrribute 的常见的属性 key 有:

  • kSecAttrService:服务
  • kSecAttrServer:服务器域名或IP地址
  • kSecAttrAccount:账号
  • kSecAttrAccessGroup:应用之间共享 keychain 中的数据的标识
  • kSecMatchLimit:返回搜索结果,对应的 value 有:
    • kSecMatchLimitOne:一个
    • kSecMatchLimitAll:全部

SecValue

keychain 中的密码项,用来存储对应的密码。

方法

操作 keychain 有四个方法:增、删、改、查。

新增

OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result)

SecItemAdd 用于向 Keychain 中新增一条数据。

参数:

  • attributes 表示数据,
  • result 表示新增操作后,指向新增数据的引用,如果不需要用到这条数据,可以传入NULL。

删除

OSStatus SecItemDelete(CFDictionaryRef query)

SecItemDelete 删除符合查询条件的记录。

参数:

  • query 表示查询条件

修改

OSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate)

SecItemUpdate 更新 Keychain 里的记录。

参数:

  • query 表示查询条件
  • attributesToUpdate 表示更新搜索结果的新值。

查找

OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result)

SecItemCopyMatching 表示查询 Keychain 中符号条件的记录。

参数:

  • query 查询条件
  • result 查询结果的引用。

更多

属性列表

  • CFTypeRef kSecAttrAccessible; //可访问性 类型透明,对应的值有:
    • CFTypeRef kSecAttrAccessibleWhenUnlocked; //解锁可访问,备份
    • CFTypeRef kSecAttrAccessibleAfterFirstUnlock; //第一次解锁后可访问,备份
    • CFTypeRef kSecAttrAccessibleAlways; //一直可访问,备份
    • CFTypeRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly; //解锁可访问,不备份
    • CFTypeRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly;//第一次解锁后可访问,不备份
    • CFTypeRef kSecAttrAccessibleAlwaysThisDeviceOnly; //一直可访问,不备份
  • CFTypeRef kSecAttrCreationDate; //创建日期 CFDateRef
  • CFTypeRef kSecAttrModificationDate; //最后一次修改日期 CFDateRef
  • CFTypeRef kSecAttrDescription; //描述 CFStringRef
  • CFTypeRef kSecAttrComment; //注释 CFStringRef
  • CFTypeRef kSecAttrCreator; //创建者 CFNumberRef(4字符,如'aLXY')
  • CFTypeRef kSecAttrType; //类型 CFNumberRef(4字符,如'aTyp')
  • CFTypeRef kSecAttrLabel; //标签(给用户看) CFStringRef
  • CFTypeRef kSecAttrIsInvisible; // 是否隐藏,值类型为 CFBooleanRef,有:
    • kCFBooleanTrue
    • kCFBooleanFalse
  • CFTypeRef kSecAttrIsNegative; //是否具有密码,表示当前的item是否只是一个占位项,或者说是只有key没有value。值类型为 CFBooleanRef
    • kCFBooleanTrue
    • kCFBooleanFalse
  • CFTypeRef kSecAttrAccount; //账户名 CFStringRef
  • CFTypeRef kSecAttrService; //所具有服务 CFStringRef
  • CFTypeRef kSecAttrGeneric; //用户自定义内容 CFDataRef
  • CFTypeRef kSecAttrSecurityDomain; //网络安全域 CFStringRef
  • CFTypeRef kSecAttrServer; //服务器域名或IP地址 CFStringRef
  • CFTypeRef kSecAttrProtocol; //协议类型 CFNumberRef,值有
    • CFTypeRef kSecAttrProtocolFTP; //
    • CFTypeRef kSecAttrProtocolFTPAccount; //
    • CFTypeRef kSecAttrProtocolHTTP; //
    • CFTypeRef kSecAttrProtocolIRC; //
    • CFTypeRef kSecAttrProtocolNNTP; //
    • CFTypeRef kSecAttrProtocolPOP3; //
    • CFTypeRef kSecAttrProtocolSMTP; //
    • CFTypeRef kSecAttrProtocolSOCKS; //
    • CFTypeRef kSecAttrProtocolIMAP; //
    • CFTypeRef kSecAttrProtocolLDAP; //
    • CFTypeRef kSecAttrProtocolAppleTalk; //
    • CFTypeRef kSecAttrProtocolAFP; //
    • CFTypeRef kSecAttrProtocolTelnet; //
    • CFTypeRef kSecAttrProtocolSSH; //
    • CFTypeRef kSecAttrProtocolFTPS; //
    • CFTypeRef kSecAttrProtocolHTTPS; //
    • CFTypeRef kSecAttrProtocolHTTPProxy; //
    • CFTypeRef kSecAttrProtocolHTTPSProxy; //
    • CFTypeRef kSecAttrProtocolFTPProxy; //
    • CFTypeRef kSecAttrProtocolSMB; //
    • CFTypeRef kSecAttrProtocolRTSP; //
    • CFTypeRef kSecAttrProtocolRTSPProxy; //
    • CFTypeRef kSecAttrProtocolDAAP; //
    • CFTypeRef kSecAttrProtocolEPPC; //
    • CFTypeRef kSecAttrProtocolIPP; //
    • CFTypeRef kSecAttrProtocolNNTPS; //
    • CFTypeRef kSecAttrProtocolLDAPS; //
    • CFTypeRef kSecAttrProtocolTelnetS; //
    • CFTypeRef kSecAttrProtocolIMAPS; //
    • CFTypeRef kSecAttrProtocolIRCS; //
    • CFTypeRef kSecAttrProtocolPOP3S; //
  • CFTypeRef kSecAttrAuthenticationType; //认证类型 CFNumberRef,对应的值有:
    • CFTypeRef kSecAttrAuthenticationTypeNTLM; //
    • CFTypeRef kSecAttrAuthenticationTypeMSN; //
    • CFTypeRef kSecAttrAuthenticationTypeDPA; //
    • CFTypeRef kSecAttrAuthenticationTypeRPA; //
    • CFTypeRef kSecAttrAuthenticationTypeHTTPBasic; //
    • CFTypeRef kSecAttrAuthenticationTypeHTTPDigest; //
    • CFTypeRef kSecAttrAuthenticationTypeHTMLForm; //
    • CFTypeRef kSecAttrAuthenticationTypeDefault; //
  • CFTypeRef kSecAttrPort; //网络端口 CFNumberRef
  • CFTypeRef kSecAttrPath; //访问路径 CFStringRef
  • CFTypeRef kSecAttrSubject; //X.500主题名称 CFDataRef
  • CFTypeRef kSecAttrIssuer; //X.500发行者名称 CFDataRef
  • CFTypeRef kSecAttrSerialNumber; //序列号 CFDataRef
  • CFTypeRef kSecAttrSubjectKeyID; //主题ID CFDataRef
  • CFTypeRef kSecAttrPublicKeyHash; //公钥Hash值 CFDataRef
  • CFTypeRef kSecAttrCertificateType; //证书类型 CFNumberRef
  • CFTypeRef kSecAttrCertificateEncoding; //证书编码类型 CFNumberRef
  • CFTypeRef kSecAttrKeyClass; //加密密钥类 CFTypeRef,对应的值 有
    • CFTypeRef kSecAttrKeyClassPublic; //公钥
    • CFTypeRef kSecAttrKeyClassPrivate; //私钥
    • CFTypeRef kSecAttrKeyClassSymmetric; //对称密钥
  • CFTypeRef kSecAttrApplicationLabel; //标签(给程序使用) CFStringRef(通常是公钥的Hash值)
  • CFTypeRef kSecAttrIsPermanent; //是否永久保存加密密钥 CFBooleanRef
  • CFTypeRef kSecAttrApplicationTag; //标签(私有标签数据) CFDataRef
  • CFTypeRef kSecAttrKeyType; //加密密钥类型(算法) CFNumberRef,值有
    • extern const CFTypeRef kSecAttrKeyTypeRSA;
  • CFTypeRef kSecAttrKeySizeInBits; //密钥总位数 CFNumberRef
  • CFTypeRef kSecAttrEffectiveKeySize; //密钥有效位数 CFNumberRef
  • CFTypeRef kSecAttrCanEncrypt; //密钥是否可用于加密 CFBooleanRef
  • CFTypeRef kSecAttrCanDecrypt; //密钥是否可用于加密 CFBooleanRef
  • CFTypeRef kSecAttrCanDerive; //密钥是否可用于导出其他密钥 CFBooleanRef
  • CFTypeRef kSecAttrCanSign; //密钥是否可用于数字签名 CFBooleanRef
  • CFTypeRef kSecAttrCanVerify; //密钥是否可用于验证数字签名 CFBooleanRef
  • CFTypeRef kSecAttrCanWrap; //密钥是否可用于打包其他密钥 CFBooleanRef
  • CFTypeRef kSecAttrCanUnwrap; //密钥是否可用于解包其他密钥 CFBooleanRef
  • CFTypeRef kSecAttrAccessGroup; //访问组 CFStringRef

钥匙串项对应的属性

不同类型的钥匙串项对应的属性不同:

kSecClassGenericPassword (一般密码) 对应属性:

  • kSecAttrAccessible
  • kSecAttrAccessGroup
  • kSecAttrCreationDate
  • kSecAttrModificationDate
  • kSecAttrDescription
  • kSecAttrComment
  • kSecAtt rCreator
  • kSecAttrType
  • kSecAttrLabel
  • kSecAttrIsInvisible
  • kSecAttrIsNegative
  • kSecAttrAccount
  • kSecAttrService
  • kSecAttrGeneric

kSecClassInternetPassword 网络密码,对应属性

  • kSecAttrAccessible
  • kSecAttrAccessGroup
  • kSecAttrCreationDate
  • kSecAttrModificationDate
  • kSecAttrDescription
  • kSecAttrComment
  • kSecAttrCreator
  • kSecAttrType
  • kSecAttrLabel
  • kSecAttrIsInvisible
  • kSecAttrIsNegative
  • kSecAttrAccount
  • kSecAttrSecurityDomain
  • kSecAttrServer
  • kSecAttrProtocol
  • kSecAttrAuthenticationType
  • kSecAttrPort
  • kSecAttrPath

kSecClassCertificate 证书,对应属性

  • kSecAttrAccessible
  • kSecAttrAccessGroup
  • kSecAttrCertificateType
  • kSecAttrCertificateEncoding
  • kSecAttrLabel
  • kSecAttrSubject
  • kSecAttrIssuer
  • kSecAttrSerialNumber
  • kSecAttrSubjectKeyID
  • kSecAttrPublicKeyHash

kSecClassKey 密钥,对应属性

  • kSecAttrAccessible
  • kSecAttrAccessGroup
  • kSecAttrKeyClass
  • kSecAttrLabel
  • kSecAttrApplicationLabel
  • kSecAttrIsPermanent
  • kSecAttrApplicationTag
  • kSecAttrKeyType
  • kSecAttrKeySizeInBits
  • kSecAttrEffectiveKeySize
  • kSecAttrCanEncrypt
  • kSecAttrCanDecrypt
  • kSecAttrCanDerive
  • kSecAttrCanSign
  • kSecAttrCanVerify
  • kSecAttrCanWrap
  • kSecAttrCanUnwrap

kSecClassIdentity 身份证书(带私钥的证书),对应属性

  • 证书属性
  • 私钥属性

搜索

  • CFTypeRef kSecMatchPolicy; //指定策略 SecPolicyRef
  • CFTypeRef kSecMatchItemList; //指定搜索范围 CFArrayRef(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef,CFDataRef)数组内的类型必须唯一。仍然会搜索钥匙串,但是搜索结果需要与该数组取交集作为最终结果。
  • CFTypeRef kSecMatchSearchList; //
  • CFTypeRef kSecMatchIssuers; //指定发行人数组 CFArrayRef
  • CFTypeRef kSecMatchEmailAddressIfPresent; //指定邮件地址 CFStringRef
  • CFTypeRef kSecMatchSubjectContains; //指定主题 CFStringRef
  • CFTypeRef kSecMatchCaseInsensitive; //指定是否不区分大小写 CFBooleanRef
    • kCFBooleanTrue 不区分大小写
    • kCFBooleanFalse 区分大小写(默认值为 false)
  • CFTypeRef kSecMatchTrustedOnly; //指定只搜索可信证书 CFBooleanRef:
    • kCFBooleanTrue 只搜索可信证书
    • kCFBooleanFalse 全部证书(默认值为 false)
  • CFTypeRef kSecMatchValidOnDate; //指定有效日期 CFDateRef
    • kCFNull 表示今天
  • CFTypeRef kSecMatchLimit; //指定结果数量 CFNumberRef,对应的值有:
    • CFTypeRef kSecMatchLimitOne; //首条结果
    • CFTypeRef kSecMatchLimitAll; //全部结果

列表

  • CFTypeRef kSecUseItemList; //CFArrayRef(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef, CFDataRef)数组内的类型必须唯一。用户提供用于查询的列表。当这个列表被提供的时候,不会再搜索钥匙串。

返回值类型

可以同时指定多种返回值类型

  • CFTypeRef kSecReturnData; //返回数据(CFDataRef) CFBooleanRef
  • CFTypeRef kSecReturnAttributes; //返回属性字典(CFDictionaryRef) CFBooleanRef
  • CFTypeRef kSecReturnRef; //返回实例(SecKeychainItemRef, SecKeyRef, SecCertificateRef, SecIdentityRef, or CFDataRef) CFBooleanRef
  • CFTypeRef kSecReturnPersistentRef; //返回持久型实例(CFDataRef) CFBooleanRef

写入值类型

  • CFTypeRef kSecValueData;
  • CFTypeRef kSecValueRef;
  • CFTypeRef kSecValuePersistentRef;

参考链接

blog.sina.cn/dpool/blog/… www.jianshu.com/p/fec5a3eb7…