keychain 的结构
一个 keychain 结构的 Item 由三部分组成:
- Class
- Atrribute
- 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;