版本信息最后核对:2026-10-25
管理 macOS 登录钥匙串、系统钥匙串、证书私钥与命令行访问权限。
钥匙串保存密码、证书、私钥、登录令牌和安全备注。每个 macOS 用户有一个默认的登录钥匙串,文件通常在 ~/Library/Keychains/login.keychain-db,随用户登录解锁;系统钥匙串位于 /Library/Keychains/System.keychain,保存与具体用户无关的网络凭据和 PKI 身份,修改通常需要 root;System Roots 保存互联网根证书,受系统完整性保护,不应手动改动。iCloud 钥匙串和“密码”应用中的网站密码由系统单独管理,security 不是读取它们的入口,自动化也不应尝试绕过这层保护。
security 是钥匙串的命令行入口:list-keychains、default-keychain、login-keychain 管理搜索列表和默认项,create-keychain、delete-keychain 创建或删除钥匙串,unlock-keychain、lock-keychain、set-keychain-settings 控制锁定状态,find-generic-password、add-generic-password、find-internet-password 读写密码项,find-certificate、find-identity、import、export 处理证书与身份,set-key-partition-list 调整私钥的访问分区。
“身份”(identity)是证书和对应私钥的组合,只有两者都在、证书未过期、信任链完整,代码签名和客户端认证才能使用。导入 p12 时,-T 指定允许访问私钥的应用,-A 则允许所有应用无提示访问,man page 明确标注它不安全;CI 里更常见的做法是导入时只信任 codesign,再用 set-key-partition-list 放宽到签名工具链需要的最小范围。钥匙串 ACL、应用签名和分区列表共同决定会不会弹出授权框,单看“钥匙串已解锁”不足以解释所有提示。
授权提示的根源在访问控制,而不只是锁状态。系统根据调用程序的签名、Keychain-access-groups、ACL 和私钥分区列表判断是否放行;同一把私钥被不同路径或不同签名的程序调用,可能得到不同结果。终端、IDE、构建脚本和远程会话可能被系统视为不同调用者,所以“我在终端里能用”不代表 CI 也能用。排查时记录是谁在请求、请求哪个项目、以什么身份运行,再决定是精确授权还是改用专用钥匙串。
解锁生命周期也常被误解。登录钥匙串通常在登录时自动解锁,但锁屏不等于锁钥匙串;需要时可以手动 security lock-keychain,或在钥匙串访问中设置睡眠时锁定。用户通过系统设置正常修改登录密码时,系统会同步钥匙串密码;如果是管理员重置密码、目录服务变更或迁移账户,钥匙串密码可能与登录密码不一致,于是持续弹出“更新钥匙串密码”或授权框。重置登录钥匙串会创建新钥匙串,旧钥匙串里的项目不会自动迁移,操作前必须备份。
影响范围:
security delete-keychain会删除整个钥匙串文件及其中的密码、证书和私钥;delete-identity、delete-certificate会移除签名身份或信任材料;list-keychains -s会替换搜索列表而不是追加;set-key-partition-list和导入时的-A会扩大哪些程序可以无提示访问私钥;security export导出的 p12 若密码薄弱或落在共享目录,等于把私钥复制出去;在脚本里用-p 密码解锁会把密码暴露在进程参数、shell 历史和日志中。前置条件:先在测试机或独立钥匙串验证,导出并加密备份现有钥匙串,记录原搜索列表、项目来源和用途,确认有本地管理员和可恢复的登录方式;系统钥匙串的改动会影响所有用户,必须先确认影响范围。恢复方式:用security import恢复备份,用unlock-keychain解锁,恢复原搜索列表,在钥匙串访问中重新导入证书和私钥;删除登录钥匙串后只能重建并逐项补回,没有回收站。
# 1. 查看搜索列表、默认钥匙串和登录钥匙串
% security list-keychains -d user
% security default-keychain
% security login-keychain
# 2. 手动解锁和锁定登录钥匙串;不带 -p 时会交互提示
% security unlock-keychain ~/Library/Keychains/login.keychain-db
% security lock-keychain ~/Library/Keychains/login.keychain-db
# 3. 查找可用的签名身份;为空说明证书、私钥或信任链有问题
% security find-identity -v -p codesigning
# 4. 查找证书并输出 PEM;这里只导出证书,不包含私钥
% security find-certificate -c "Developer ID Application" -p ~/Library/Keychains/login.keychain-db
% security find-certificate -a -c "Example CA" -p > example-ca.pem
# 5. 在 CI 中创建专用钥匙串,导入 p12 且只授权 codesign 访问私钥
% security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
% security import cert.p12 -k build.keychain -P "$P12_PASSWORD" -T /usr/bin/codesign
# 6. 解锁专用钥匙串,并允许 codesign 非交互访问私钥
% security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
% security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain
# 先记录原搜索列表;-s 会替换列表,而不是追加
% security list-keychains -d user
% security list-keychains -d user -s build.keychain
# 任务结束后清理并恢复原搜索列表,不要只删除钥匙串
% security delete-keychain build.keychain
# 再用步骤 1 记录的原搜索列表执行 list-keychains -s 恢复
# 7. 读取通用密码项;-w 输出明文,避免重定向到日志或工单
% security find-generic-password -s deploy-token -w
find-identity -v -p codesigning 返回 0 个身份:证书可能过期或被吊销,私钥不在同一个钥匙串,信任链不完整,或该钥匙串没加入搜索列表。依次用 find-certificate、钥匙串访问和 security list-keychains 核对,不要急着重导。set-key-partition-list。无图形会话的 runner 无法点“允许”,所以必须提前配置非交互访问;不要用 -A 图省事。security 仍然弹出授权框:这是项目的 ACL 或私钥分区列表没有包含当前调用程序,不是钥匙串锁没锁。确认调用者路径和签名,使用 -T 精确授权,或为 CI 私钥设置分区列表;不要对来源不明的程序选择“始终允许”。find-generic-password -w 会把密码明文写到 stdout,add-generic-password -w 明文 又会进入进程参数和 shell 历史。需要交互输入时把 -w 放在末尾且不跟值;CI 使用受保护的变量、临时钥匙串和日志脱敏。security 可读的项目:它由系统和“密码”应用管理,受不同保护机制约束。需要自动化凭据时,应单独创建受控的通用密码项或使用专用令牌,而不是尝试导出用户的全量密码库。/Library/Keychains/System.keychain 中的项目供所有用户和系统服务使用,错误删除会影响网络认证、VPN 或证书校验;System Roots 受 SIP 保护且不应手工修改。需要新增企业根证书时,优先通过描述文件或 MDM 分发。security dump-keychain 会输出大量项目元数据,部分操作还会触发授权提示;不要把完整输出贴进工单。排查只需要项目属性时,优先用 find-generic-password、find-certificate 加上精确的 service 或名称过滤。ssh-add 使用 --apple-use-keychain,旧写法是 -K;配置 UseKeychain yes 和 AddKeysToAgent yes 后再验证,不要把口令写进脚本。security — 钥匙串、证书与签名身份的完整命令页。codesign — 使用钥匙串身份签名并验证产物。ssh — SSH 密钥、代理与钥匙串集成。mdm — 描述文件下发的证书与身份。filevault — 恢复密钥与 FileVault 主钥匙串。合上页面,先回答,再展开对照。
codesign 一直等待钥匙串授权,常见原因是什么?应如何配置?security 读不到“密码”应用里看到的网站密码?自动化应怎么取凭据?codesign,再执行 set-key-partition-list,避免使用 -A。security 不是其读取接口。自动化应使用专用令牌或单独创建的通用密码项,并限制访问范围。
小程序版
微信扫码,随时查命令