钥匙串访问控制
通过生物识别和设备解锁保护项目。
钥匙串访问控制 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。
控制何时可以读取机密数据
存储机密数据只是完成了一半的工作——您还必须控制它在何时可以被读取。钥匙串提供了可访问性类别和访问控制标志,可以要求项目必须在设备解锁、输入密码或通过生物识别后才能访问。如果设备丢失,这些机制可以保护数据。
import Security
// Two layers of control:
// kSecAttrAccessible -> when readable (lock state)
// SecAccessControl -> user presence / biometricskSecAttrAccessible 属性键
kSecAttrAccessible 会在添加项目时设置其可访问性类别。它决定项目是始终可用、仅在首次解锁后可用,还是仅在设备处于解锁状态时可用。请选择功能允许的最严格级别。
import Security
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: "user",
kSecValueData as String: Data("secret".utf8),
kSecAttrAccessible as String:
kSecAttrAccessibleWhenUnlocked
]
_ = queryWhenUnlocked
kSecAttrAccessibleWhenUnlocked 使项目仅在设备解锁期间可读。设备锁定时运行的后台任务无法访问它。对于大多数会话令牌,这是合理的默认设置。
import Security
// Readable only while unlocked; blocked when locked.
let level = kSecAttrAccessibleWhenUnlocked
_ = levelAfterFirstUnlock
kSecAttrAccessibleAfterFirstUnlock 会使项目从设备启动后的首次解锁开始保持可读,直到下一次重启为止——即使之后设备再次锁定,项目仍然可读。对于后台进程所需的机密数据(例如处理推送所需的令牌),可以使用它。
import Security
// Available after the first unlock post-boot,
// including while subsequently locked.
let level = kSecAttrAccessibleAfterFirstUnlock
_ = levelThisDeviceOnly 变体
每个可访问性类别都有一个 ...ThisDeviceOnly 形式。这些项目不会包含在加密备份中,也不会迁移到新设备。对于绝不应离开当前硬件的密钥,请使用这些形式。
import Security
// Never backed up, never migrated:
let local = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
_ = local设置密码时
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly 仅在用户设置了密码时存储项目;如果用户移除密码,该项目也会被删除。它可以保证机密数据始终受到密码保护。
import Security
let level =
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
// Item vanishes if the user disables their passcode.
_ = level使用 SecAccessControl 要求用户在场
除了锁定状态之外,SecAccessControlCreateWithFlags 还可以构建一个策略,要求用户在读取时主动进行身份验证——使用生物识别或密码。您可以通过 kSecAttrAccessControl 附加该策略,以替代可访问性属性或与其同时使用。
import Security
func makeControl() -> SecAccessControl? {
return SecAccessControlCreateWithFlags(
nil,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
.userPresence,
nil)
}访问控制标志
标志可以进一步细化要求:.userPresence 允许使用生物识别或密码回退;.biometryCurrentSet 会在已录入的指纹或面容发生变化时使项目失效;.devicePasscode 会强制要求输入设备密码。您可以组合使用它们来表达安全需求。
import Security
// .userPresence -> biometric OR passcode
// .biometryAny -> any enrolled biometric
// .biometryCurrentSet -> invalidate on biometric change
// .devicePasscode -> passcode only
let flags: SecAccessControlCreateFlags = [.userPresence]
_ = flags添加受保护的项目
要存储受生物识别保护的机密数据,请将 SecAccessControl 对象放在 kSecAttrAccessControl 下。之后的任何读取都会先提示用户进行身份验证,然后才返回数据。
import Security
func saveProtected(_ data: Data, account: String,
control: SecAccessControl) -> Bool {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecValueData as String: data,
kSecAttrAccessControl as String: control]
return SecItemAdd(query as CFDictionary, nil)
== errSecSuccess
}读取时提示用户
读取受保护的项目会自动触发身份验证界面。您可以通过 kSecUseOperationPrompt 提供原因字符串,让提示说明为什么需要访问。读取操作会一直阻塞,直到用户完成身份验证或取消操作。
import Security
func readProtected(account: String) -> Data? {
let query: [String: Any] = [
kSecClass as String: kSecClassGenericPassword,
kSecAttrAccount as String: account,
kSecReturnData as String: true,
kSecUseOperationPrompt as String:
String(localized: "Unlock your saved key")]
var out: CFTypeRef?
return SecItemCopyMatching(query as CFDictionary,
&out) == errSecSuccess ? out as? Data : nil
}选择合适的级别
请根据风险匹配策略:
- 后台使用的会话令牌:
AfterFirstUnlock。 - 仅用户界面使用的令牌:
WhenUnlocked。 - 高价值机密数据:使用带有
.userPresence的SecAccessControl,以及ThisDeviceOnly类别。
更严格的设置更安全,但会中断后台访问——请在两者之间取得平衡。
import Security
// High-value: biometric-gated, device-bound, no backup
let control = SecAccessControlCreateWithFlags(
nil,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
.userPresence, nil)
_ = control快速检查
请回忆一下,哪种可访问性类别适合后台所需的机密数据。
回顾
您已经学习了如何限制钥匙串项目的访问:
kSecAttrAccessible设置项目在不同锁定状态下的可用性:WhenUnlocked、AfterFirstUnlock,以及不会使用备份的...ThisDeviceOnly变体。WhenPasscodeSetThisDeviceOnly将项目与设备是否设置密码关联起来。- 带有
.userPresence或.biometryCurrentSet等标志的SecAccessControl会要求在读取时进行身份验证。 - 请选择在满足访问模式的前提下最严格的级别。
常见问题解答
「钥匙串访问控制」课时是免费的吗?
是的 — 「钥匙串访问控制」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。
「钥匙串访问控制」这节课中我会学到什么?
通过生物识别和设备解锁保护项目。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Swift Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「钥匙串访问控制」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Swift Academy 课中编写并运行代码吗?
能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。