mcpField
S
swift-security-expert

swift-security-expert

github.com/ivan-magda安全40855 次安装19 周前更新
代码仓库

关于 swift-security-expert

swift-security-expert 是面向 Apple 平台开发者的安全参考技能,用于实现、审查和更新安全功能。内容涵盖 Keychain、生物识别、CryptoKit 及合规检查,并以文档依据和清单为基础。

主要功能

  1. 01Keychain 实现与审查
  2. 02生物识别认证指南
  3. 03CryptoKit 模式参考
  4. 04凭据迁移指导
  5. 05安全测试与合规映射

适用场景

  1. 01审查现有 Keychain 代码
  2. 02将机密移出不安全存储
  3. 03添加 Face ID 或 Touch ID 保护
  4. 04按 OWASP 要求检查安全代码

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ivan-magda/swift-security-skill --skill swift-security-expert

安装后在 Claude Code 中输入/swift-security-expert确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
biometric-authentication.md
certificate-trust.md
common-anti-patterns.md
compliance-owasp-mapping.md
credential-storage-patterns.md
cryptokit-public-key.md
cryptokit-symmetric.md
keychain-access-control.md
keychain-fundamentals.md
keychain-item-classes.md
keychain-sharing.md
migration-legacy-stores.md
secure-enclave.md
testing-security-code.md

详细介绍

钥匙串与安全专家技能

理念: 不预设立场,以正确性为重。这项技能提供事实、经过验证的模式和 Apple 文档记录的最佳实践,而非架构要求。最低部署目标为 iOS 13+,现代建议以 iOS 17+ 为目标,并提供面向未来的 iOS 26(后量子)指导。每种代码模式均以 Apple 文档、DTS 工程师的文章(Quinn "The Eskimo!")、WWDC 会议和 OWASP MASTG 为依据,而非仅凭记忆。

这项技能是什么: 用于审查、改进和实现 Apple 平台上的钥匙串操作、生物识别认证、CryptoKit 密码学、凭证生命周期管理、证书信任和合规映射的参考资料。

这项技能不是什么: 网络指南、服务端安全参考或 App Transport Security 手册。TLS 配置、服务端证书管理和后端认证架构不在范围内,除非它们直接涉及客户端钥匙串或信任 API。


决策树

确定用户的意图,然后遵循相应分支。如果意图不明确,请提问。

                        ┌─────────────────────┐
                        │  What is the task?   │
                        └─────────┬───────────┘
               ┌──────────────────┼──────────────────┐
               ▼                  ▼                  ▼
          ┌─────────┐      ┌───────────┐      ┌────────────┐
          │ REVIEW  │      │  IMPROVE  │      │ IMPLEMENT  │
          │         │      │           │      │            │
          │ Audit   │      │ Migrate / │      │ Build from │
          │ existing│      │ modernize │      │ scratch    │
          │ code    │      │ existing  │      │            │
          └────┬────┘      └─────┬─────┘      └─────┬──────┘
               │                 │                   │
               ▼                 ▼                   ▼
        Run Top-Level      Identify gap         Identify which
        Review Checklist   (legacy store?        domain(s) apply,
        (§ below) against  wrong API?            load reference
        the code.          missing auth?)        file(s), follow
        Flag each item     Load migration +      ✅ patterns.
        as ✅ / ❌ /       domain-specific        Implement with
        ⚠️ N/A.           reference files.       add-or-update,
        For each ❌,       Follow ✅ patterns,    proper error
        cite the           verify with domain     handling, and
        reference file     checklist.             correct access
        and specific                              control from
        section.                                  the start.

分支 1 — REVIEW(审计现有代码)

目标: 系统地评估现有钥匙串/安全代码的正确性、安全性和合规性。

流程:

  1. 对正在审查的代码执行顶层审查清单(见下文)。为每项评分:✅ / ❌ / ⚠️ N/A。
  2. 对于每个 ❌ 问题,加载引用的参考文件,并找到具体的反模式或正确模式。
  3. 交叉检查反模式——对照 common-anti-patterns.md 中的全部 10 项检查代码。特别注意:将 UserDefaults 用于机密信息(#1)、硬编码密钥(#2)、将 LAContext.evaluatePolicy() 作为唯一认证关卡(#3)、忽略 OSStatus(#4)。
  4. 检查合规性——如果项目要求符合 OWASP MASVS 或满足企业审计要求,请将发现的问题映射到 compliance-owasp-mapping.md 中的 M1、M3、M9、M10 类别。
  5. 报告格式: 对于每项发现,说明:问题所在 → 涉及该问题的参考文件 → ✅ 正确模式 → 严重性(CRITICAL / HIGH / MEDIUM)。

审查主要参考文件:

  • 从以下文件开始:common-anti-patterns.md(核心参考,涵盖 10 种最危险的模式)
  • 然后根据代码的功能查看特定领域的文件
  • 最后查看:compliance-owasp-mapping.md(如涉及合规性)

分支 2 — IMPROVE(迁移 / 现代化)

目标: 将现有代码从不安全存储、已弃用 API 或旧模式升级为当前最佳实践。

流程:

  1. 确定迁移类型:

    • 不安全存储 → 钥匙串:加载 migration-legacy-stores.md + credential-storage-patterns.md
    • 旧版 Security 框架 → CryptoKit:加载 cryptokit-symmetric.md 或 cryptokit-public-key.md + migration-legacy-stores.md
    • RSA → 椭圆曲线:加载 cryptokit-public-key.md(RSA 迁移部分)
    • GenericPassword → InternetPassword(AutoFill):加载 keychain-item-classes.md(迁移部分)
    • 仅使用 LAContext → 绑定钥匙串的生物识别:加载 biometric-authentication.md
    • 基于文件的钥匙串 → 数据保护钥匙串(macOS):加载 keychain-fundamentals.md(TN3137 部分)
    • 单个应用 → 共享钥匙串(扩展):加载 keychain-sharing.md
    • 叶证书固定 → SPKI/CA 固定:加载 certificate-trust.md
  2. 遵循相关参考文件中的迁移模式。每个迁移部分都包含:迁移前验证、原子迁移步骤、安全删除旧数据、迁移后验证。

  3. 迁移完成后,执行参考文件中的特定领域清单。

  4. 使用 testing-security-code.md 中的指导验证没有回归问题。


分支 3 — 实现(从头构建)

目标: 从一开始就正确构建新的钥匙串/安全功能。

流程:

  1. 确定任务涉及哪些领域。 使用下方的领域选择指南。
  2. 加载相关参考文件。 遵循 ✅ 代码模式——核心安全逻辑绝不偏离这些模式。
  3. 将核心指南(如下)应用于每项实现。
  4. 在认为实现完成前,运行对应领域的检查清单。
  5. 添加测试,遵循 testing-security-code.md——单元测试使用基于协议的抽象;在设备上进行集成测试时使用真实钥匙串。

领域选择指南:

如果任务涉及……加载这些参考文件
存储/读取密码或令牌keychain-fundamentals.md + credential-storage-patterns.md
选择要使用的 kSecClasskeychain-item-classes.md
设置项目的可访问时机keychain-access-control.md
Face ID / Touch ID 验证biometric-authentication.md + keychain-access-control.md
硬件支持的密钥secure-enclave.md
加密/哈希数据cryptokit-symmetric.md
签名/密钥交换/HPKEcryptokit-public-key.md
OAuth 令牌/API 密钥/注销credential-storage-patterns.md
在应用和扩展之间共享keychain-sharing.md
TLS 固定/客户端证书certificate-trust.md
替换 UserDefaults/plist 密钥migration-legacy-stores.md
编写安全代码测试testing-security-code.md
企业审计/OWASP 合规compliance-owasp-mapping.md

核心准则

以下七条规则不可妥协。所有钥匙串/安全实现都必须满足这些要求。

1. 绝不忽略 OSStatus。 每个 SecItem* 调用都会返回一个 OSStatus。使用完整的 switch,至少涵盖:errSecSuccess、errSecDuplicateItem(-25299)、errSecItemNotFound(-25300)、errSecInteractionNotAllowed(-25308)。默默丢弃返回值是大多数钥匙串问题的根源。→ keychain-fundamentals.md

2. 绝不将 LAContext.evaluatePolicy() 单独用作身份验证门禁。 此方法返回一个 Bool,可通过 Frida 在运行时轻易篡改。生物识别身份验证必须与钥匙串绑定:使用 .biometryCurrentSet 的 SecAccessControl 保护机密,然后让钥匙串在 SecItemCopyMatching 期间提示用户使用 Face ID/Touch ID。钥匙串会在 Secure Enclave 中处理身份验证,不存在可供篡改的 Bool。→ biometric-authentication.md

3. 绝不将机密存储在 UserDefaults、Info.plist、.xcconfig 或 NSCoding 存档中。 这些方式会产生明文文件,可从未加密的备份中读取。Keychain 是 Apple 唯一认可的凭据存储位置。→ credential-storage-patterns.md、common-anti-patterns.md

4. 绝不在 @MainActor 上调用 SecItem*。 每次钥匙串调用都是与 securityd 进行的 IPC 往返,会阻塞调用线程。所有钥匙串访问都应使用专用的 actor(iOS 17+)或串行 DispatchQueue(iOS 13–16)。→ keychain-fundamentals.md

5. 始终显式设置 kSecAttrAccessible。 系统默认值(kSecAttrAccessibleWhenUnlocked)会导致所有后台操作失败,也可能不符合你的威胁模型。选择满足访问模式的最严格类别。后台任务使用:kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly。最高敏感级别使用:kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly。→ keychain-access-control.md

6. 始终采用先添加、重复时再更新的模式。 先调用 SecItemAdd,遇到 errSecDuplicateItem 时再调用 SecItemUpdate。绝不先删除再添加(这会造成竞态窗口,并破坏持久引用)。调用 SecItemAdd 时,绝不忽略重复项情况。→ keychain-fundamentals.md

7. 在 macOS 上始终使用数据保护钥匙串。 对 macOS 目标平台上的每个 SecItem* 调用,都设置 kSecUseDataProtectionKeychain: true。否则,查询会被悄然路由到旧版基于文件的钥匙串,其行为不同,会忽略不支持的属性,并且无法使用生物识别保护或 Secure Enclave 密钥。Mac Catalyst 和 iOS-on-Mac 会自动执行此操作。→ keychain-fundamentals.md


快速参考表

辅助功能常量 — 选择指南
常量可解密时机是否保留在备份中是否保留在设备迁移中后台安全使用场景
WhenPasscodeSetThisDeviceOnly设备已解锁且已设置密码❌❌❌最高安全级别的机密;移除密码后会被删除
WhenUnlockedThisDeviceOnly设备已解锁❌❌❌不需要在后台使用的设备绑定型机密
WhenUnlocked设备已解锁✅✅❌可同步的机密(系统默认值 — 避免隐式使用)
AfterFirstUnlockThisDeviceOnly首次解锁后 → 重启后❌❌✅后台任务、推送处理程序、设备绑定型数据
AfterFirstUnlock首次解锁后 → 重启后✅✅✅必须在恢复后保留的后台任务

已弃用(切勿使用): kSecAttrAccessibleAlways、kSecAttrAccessibleAlwaysThisDeviceOnly — 在 iOS 12 中已弃用。

经验法则: 需要后台访问(推送处理程序、后台刷新)?从 AfterFirstUnlockThisDeviceOnly 开始。仅在前台使用?从 WhenUnlockedThisDeviceOnly 开始。对于高价值机密,收紧为 WhenPasscodeSetThisDeviceOnly。只有在需要 iCloud 同步或备份迁移时才使用非 ThisDeviceOnly 变体。

CryptoKit 算法选择
需求算法最低 iOS 版本备注
哈希数据SHA256 / SHA384 / SHA51213SHA3_256/SHA3_512 在 iOS 18+ 中可用
验证数据(MAC)HMAC<SHA256>13始终使用恒定时间比较(内置)进行验证
加密数据(带认证)AES.GCM13256 位密钥、96 位 nonce、128 位标签。切勿在同一密钥下重复使用 nonce
加密数据(针对移动设备优化)ChaChaPoly13在不支持 AES-NI 的设备上性能更好(较旧的 Apple Watch)
对数据签名P256.Signing / Curve25519.Signing13互操作性优先时使用 P256,追求性能时使用 Curve25519
密钥协商P256.KeyAgreement / Curve25519.KeyAgreement13始终通过 HKDF 派生对称密钥,切勿使用原始共享密钥
混合公钥加密HPKE17取代手动串联 ECDH、HKDF 和 AES-GCM
硬件支持的签名SecureEnclave.P256.Signing13仅支持 P256;密钥不会离开硬件
后量子密钥交换MLKEM76826形式化验证(ML-KEM FIPS 203)
后量子签名MLDSA6526形式化验证(ML-DSA FIPS 204)
密码 → 密钥派生PBKDF2(通过 CommonCrypto)13SHA-256 迭代次数 ≥600,000(OWASP 2024)
密钥 → 密钥派生HKDF<SHA256>13先提取再扩展;始终使用 info 参数进行域分离
反模式检测 — 快速扫描

审查代码时,搜索以下模式。任何匹配项都属于发现项。 ❌ = 在用户代码中检测到的不安全模式特征。✅ = 在所引用的文件中应用纠正模式。

搜索内容反模式严重性参考
UserDefaults.standard.set + token/key/secret/password明文存储凭据严重common-anti-patterns.md #1
源代码中的硬编码 base64/hex 字符串(≥16 个字符)硬编码加密密钥严重common-anti-patterns.md #2
附近没有 SecItemCopyMatching 的 evaluatePolicy仅使用 LAContext 的生物识别门禁严重common-anti-patterns.md #3
未检查返回值 / OSStatus 的 SecItemAdd忽略错误代码高common-anti-patterns.md #4
添加字典中没有 kSecAttrAccessible隐式可访问性类别高common-anti-patterns.md #5
使用相同密钥在循环中调用 AES.GCM.Nonce()可能重复使用 nonce严重common-anti-patterns.md #6
未使用 HKDF 的 sharedSecret.withUnsafeBytes将原始共享密钥用作密钥高common-anti-patterns.md #7
kSecAttrAccessibleAlways已弃用的可访问性高keychain-access-control.md
未使用 #if !targetEnvironment(simulator) 的 SecureEnclave.isAvailable模拟器误报陷阱中secure-enclave.md
kSecAttrSynchronizable: true + ThisDeviceOnly相互矛盾的约束中keychain-item-classes.md
SecTrustEvaluate(同步,已弃用)旧式信任评估中certificate-trust.md
kSecClassGenericPassword + kSecAttrServerWeb 凭据使用了错误类别中keychain-item-classes.md

顶层审查清单

使用此清单快速检查全部 14 个领域。每项都对应一个或多个参考文件,以便深入调查。对于特定领域的深入检查,请使用各参考文件末尾的摘要清单。

  • 1. 密钥存储在 Keychain 中,而非 UserDefaults/plist/源代码中 — UserDefaults、Info.plist、.xcconfig、硬编码字符串或 NSCoding 归档中均不得包含凭据、令牌或加密密钥。直接违反 OWASP M9(不安全的数据存储)。→ common-anti-patterns.md #1–2、credential-storage-patterns.md、migration-legacy-stores.md、compliance-owasp-mapping.md

  • 2. 检查每个 OSStatus — 所有 SecItem* 调用都必须通过完整的 switch 或等效方式处理返回代码。不得忽略返回值。必须以非破坏性方式处理 errSecInteractionNotAllowed(稍后重试,绝不删除)。→ keychain-fundamentals.md、common-anti-patterns.md #4

  • 3. 生物识别身份验证与 Keychain 绑定 — 如果使用生物识别,必须通过 SecAccessControl + Keychain 访问来强制执行身份验证,而不能只使用 LAContext.evaluatePolicy()。→ biometric-authentication.md、common-anti-patterns.md #3

  • 4. 明确设置正确的辅助功能类别 — 每个 Keychain 项目都必须显式设置与其访问模式(后台与前台、绑定设备与可同步)相符的 kSecAttrAccessible 值。不得使用已弃用的 Always 常量。→ keychain-access-control.md

  • 5. 不得在 @MainActor 上调用 SecItem* — 所有 Keychain 操作都必须在专用 actor 或后台队列中执行。不得在 UI 代码、viewDidLoad 或 application(_:didFinishLaunchingWithOptions:) 中同步访问 Keychain。→ keychain-fundamentals.md

  • 6. 为每种项目类型使用正确的 kSecClass — Web 凭据使用 InternetPassword(而非 GenericPassword),以支持 AutoFill。加密密钥使用 kSecClassKey,并设置正确的 kSecAttrKeyType。应用密钥使用 GenericPassword,并设置 kSecAttrService + kSecAttrAccount。→ keychain-item-classes.md

  • 7. 正确使用 CryptoKit — 同一密钥不得重复使用 nonce。ECDH 共享密钥在用作对称密钥前,必须始终通过 HKDF 派生。SymmetricKey 材料存储在 Keychain 中,不得存储在内存或文件中。加密操作必须由基于协议的单元测试覆盖。→ cryptokit-symmetric.md、cryptokit-public-key.md、testing-security-code.md

  • 8. 遵守 Secure Enclave 的限制 — SE 密钥仅支持 P256(经典算法),不得导入(必须始终在设备上生成),且绑定设备(不得备份/同步)。可用性检查必须防范模拟器和 Keychain 访问组授权问题。→ secure-enclave.md

  • 9. 正确配置共享和访问组 — kSecAttrAccessGroup 使用完整的 TEAMID.group.identifier 格式。应用与扩展之间的授权必须一致。不得意外暴露跨应用数据。→ keychain-sharing.md

  • 10. 证书信任评估使用当前方法 — 使用 SecTrustEvaluateAsyncWithError(而非已弃用的同步 SecTrustEvaluate)。证书固定策略使用 SPKI 哈希或 NSPinnedDomains(而非叶证书固定,因为每年轮换证书会导致其失效)。→ certificate-trust.md

  • 11. macOS 以数据保护 Keychain 为目标 — 所有 macOS SecItem* 调用都必须包含 kSecUseDataProtectionKeychain: true(Mac Catalyst / iOS-on-Mac 会自动处理,无需设置)。→ keychain-fundamentals.md


参考索引

#文件一句话描述风险
1keychain-fundamentals.mdSecItem* 的增删改查、查询字典、OSStatus 处理、基于 actor 的封装、macOS TN3137 路由严重
2keychain-item-classes.md五种 kSecClass 类型、复合主键、GenericPassword 与 InternetPassword、ApplicationTag 与 ApplicationLabel高
3keychain-access-control.md七种可访问性常量、SecAccessControl 标志、数据保护等级、NSFileProtection 侧栏严重
4biometric-authentication.md与 Keychain 绑定的生物识别、LAContext 绕过漏洞、注册变更检测、回退链严重
5secure-enclave.md硬件支持的 P256 密钥、CryptoKit SecureEnclave 模块、持久化、模拟器陷阱、iOS 26 后量子密码学高
6cryptokit-symmetric.mdSHA-2/3 哈希、HMAC、AES-GCM/ChaChaPoly 加密、SymmetricKey 管理、nonce 处理、HKDF/PBKDF2高
7cryptokit-public-key.mdECDSA 签名、ECDH 密钥协商、HPKE(iOS 17+)、ML-KEM/ML-DSA 后量子密码学(iOS 26+)、曲线选择高
8credential-storage-patterns.mdOAuth2/OIDC 令牌生命周期、API 密钥存储、刷新令牌轮换、运行时机密信息、注销清理严重
9keychain-sharing.md访问组、Team ID 前缀、应用扩展、Keychain Sharing 与 App Groups 权限配置、iCloud 同步中
10certificate-trust.mdSecTrust 评估、SPKI/CA/叶证书固定、NSPinnedDomains、客户端证书(mTLS)、信任策略高
11migration-legacy-stores.mdUserDefaults/plist/NSCoding → Keychain 迁移、安全删除、首次启动清理、版本化迁移中
12common-anti-patterns.mdAI 生成代码中十大常见安全错误及 ❌/✅ 代码对、检测启发式规则、OWASP 映射严重
13testing-security-code.md基于协议的模拟、模拟器与设备差异、CI/CD Keychain、Swift Testing、变异测试中
14compliance-owasp-mapping.mdOWASP Mobile Top 10(2024)、MASVS v2.1.0、MASTG 测试 ID、M1/M3/M9/M10 映射、审计准备中

权威来源

以下是所有参考文件的主要依据。如有疑问,应优先采用这些来源,而非任何二手来源。

  • Apple Keychain Services Documentation — 权威 API 参考
  • Apple Platform Security Guide(每年更新)— 架构与加密设计
  • TN3137: "On Mac Keychain APIs and Implementations" — macOS 数据保护与基于文件的 Keychain
  • Quinn "The Eskimo!" DTS Posts — "SecItem: Fundamentals" 和 "SecItem: Pitfalls and Best Practices"(更新至 2025 年)
  • WWDC 2019 Session 709 — "Cryptography and Your Apps"(CryptoKit 介绍)
  • WWDC 2025 Session 314 — "Get ahead with quantum-secure cryptography"(ML-KEM、ML-DSA)
  • OWASP Mobile Top 10 (2024) + MASVS v2.1.0 + MASTG v2 — 合规框架
  • CISA/FBI "Product Security Bad Practices" v2.0(2025 年 1 月)— 将硬编码凭据归类为国家安全风险

Agent 行为规则

以下各节规定了 AI Agent 使用此技能时应如何行动:涵盖范围、范围之外的内容、语气校准、应避免的常见错误、如何选择参考文件,以及输出格式要求。

范围界定 — 包含内容

此技能适用于 iOS、macOS、tvOS、watchOS 和 visionOS 上的客户端 Apple 平台安全,并具有权威性:

  • Keychain Services — SecItemAdd、SecItemCopyMatching、SecItemUpdate、SecItemDelete、查询字典构建、OSStatus 处理、actor/线程隔离、macOS 上的数据保护钥匙串(TN3137)
  • Keychain 项目类别 — kSecClassGenericPassword、kSecClassInternetPassword、kSecClassKey、kSecClassCertificate、kSecClassIdentity、复合主键、AutoFill 集成
  • 访问控制 — 七个 kSecAttrAccessible 常量、SecAccessControlCreateWithFlags、数据保护层级、与 NSFileProtection 的对应关系
  • 生物识别认证 — LAContext 与钥匙串绑定、布尔门控漏洞、注册信息变更检测、回退链、evaluatedPolicyDomainState
  • Secure Enclave — CryptoKit SecureEnclave.P256 模块、硬件限制(仅支持 P256、不支持导入、不支持导出、不支持对称密钥)、通过钥匙串持久化、模拟器陷阱、iOS 26 后量子算法(ML-KEM、ML-DSA)
  • CryptoKit 对称密码学 — SHA-2/SHA-3 哈希、HMAC、AES-GCM、ChaChaPoly、SymmetricKey 生命周期、nonce 处理、HKDF、PBKDF2
  • CryptoKit 公钥密码学 — ECDSA 签名(P256/Curve25519)、ECDH 密钥协商、HPKE(iOS 17+)、ML-KEM/ML-DSA(iOS 26+)、曲线选择
  • 凭据存储模式 — OAuth2/OIDC 令牌生命周期、API 密钥存储、刷新令牌轮换、运行时获取机密、注销清理
  • 钥匙串共享 — 访问组、Team ID 前缀、keychain-access-groups 与 com.apple.security.application-groups 权限、扩展、iCloud Keychain 同步
  • 证书信任 — SecTrust 评估、SPKI/CA/叶证书固定、NSPinnedDomains、客户端证书(mTLS)、信任策略
  • 迁移 — 将 UserDefaults/plist/NSCoding 迁移到 Keychain、安全删除旧数据、首次启动清理、版本化迁移
  • 测试 — 基于协议的模拟、模拟器与设备之间的差异、CI/CD 钥匙串创建、Swift Testing 模式
  • 合规性 — OWASP Mobile Top 10(2024)、MASVS v2.1.0、MASTG v2 测试 ID、CISA/FBI 不良实践

属于范围的边缘情况: 用于 mTLS 固定的客户端证书加载(certificate-trust.md)。在 Keychain 中存储 Passkey/AutoFill 凭据(keychain-item-classes.md、credential-storage-patterns.md)。将 @AppStorage 标记为不安全存储——引导至 Keychain(common-anti-patterns.md)。

范围边界 — 不包含的内容

请勿使用此技能回答以下主题。请简要说明这些主题不在范围内,并建议查阅相关资料。

主题不包含的原因建议查阅
App Transport Security(ATS)服务端 TLS 策略,与客户端钥匙串无关Apple 的 ATS 文档、Info.plist NSAppTransportSecurity 参考
CloudKit 加密由服务器管理的密钥层级,与客户端 CryptoKit 无关CloudKit 文档、CKRecord.encryptedValues
网络安全 / URLSession TLS 配置传输层问题,与存储层无关Apple URL Loading System 文档;此技能仅涵盖 mTLS 的客户端证书加载
服务端身份验证架构后端 JWT 签发、OAuth 提供方配置OWASP ASVS(应用安全验证标准)
WebAuthn / 服务端通行密钥依赖方实现Apple“支持通行密钥”文档;此技能仅涵盖客户端 ASAuthorizationController,且仅限于其在钥匙串中存储凭据的情况
代码签名 / 配置描述文件构建和分发问题,与运行时安全无关Apple 代码签名文档
越狱检测运行时完整性问题,与加密存储无关OWASP MASTG MSTG-RESILIENCE 类别
SwiftUI @AppStorageUserDefaults 的封装——除指出其不适合存储机密信息外,均不在范围内common-anti-patterns.md 第 1 条指出了这一点;不作进一步介绍
跨平台加密(OpenSSL、LibSodium)第三方库,不属于 Apple 框架相应库的文档

语气规则

此技能不偏向任何观点,以正确性为重。语气应根据严重程度调整。

默认语气——建议性。 在以下情形中使用“可以考虑”“建议”“一种做法是”“常见模式是”:架构选择(包装类设计、actor 与 DispatchQueue 的选择)、存在多个有效方案时的算法选择(P256 与 Curve25519、AES-GCM 与 ChaChaPoly)、威胁模型不明确时的辅助功能类别选择、测试策略、代码组织。

加强语气——指令性。 仅对上述七条核心指南和 common-anti-patterns.md 中的 10 种反模式使用“始终”“绝不”“必须”。这些是安全不变量,而非风格偏好。指令性要求的完整清单:

  1. 绝不忽略 OSStatus——始终检查 SecItem* 调用的返回代码。→ keychain-fundamentals.md
  2. 绝不将 LAContext.evaluatePolicy() 单独用作身份验证门槛——始终将生物识别与钥匙串项目绑定。→ biometric-authentication.md
  3. 绝不将机密存储在 UserDefaults、Info.plist、.xcconfig 或 NSCoding 归档中。→ credential-storage-patterns.md、common-anti-patterns.md
  4. 绝不在 @MainActor 上调用 SecItem*——始终使用后台 actor 或队列。→ keychain-fundamentals.md
  5. 始终在每次 SecItemAdd 上显式设置 kSecAttrAccessible。→ keychain-access-control.md
  6. 始终使用添加或更新模式(SecItemAdd → 遇到 errSecDuplicateItem 时调用 SecItemUpdate)。→ keychain-fundamentals.md
  7. 在 macOS 目标上始终设置 kSecUseDataProtectionKeychain: true。→ keychain-fundamentals.md
  8. 绝不在同一个 AES-GCM 密钥下重复使用 nonce。→ cryptokit-symmetric.md、common-anti-patterns.md
  9. 绝不将原始 ECDH 共享密钥用作对称密钥——始终通过 HKDF 派生密钥。→ cryptokit-public-key.md、common-anti-patterns.md
  10. 绝不将 Insecure.MD5 或 Insecure.SHA1 用于安全目的。→ cryptokit-symmetric.md、common-anti-patterns.md

如果某种模式不在此清单中,请使用建议性语气。不要将警告升级到参考文件所支持的程度之上。

拒绝请求时的语气。 如果查询超出范围,请直截了当地说明,但不要显得轻蔑:“此技能涵盖客户端钥匙串和 CryptoKit。有关 ATS 配置,Apple 的 NSAppTransportSecurity 文档是合适的参考资料。”说明范围边界,建议替代方案,然后继续。


常见 AI 错误——最可能出现的 10 种错误输出

在定稿前,检查以下 10 种错误。每项都链接到包含正确模式的参考文件。 每项都特意配对:❌ 表示错误的生成行为,✅ 表示应采用的纠正模式。

错误 #1——将 LAContext.evaluatePolicy() 生成为唯一的生物识别门槛。 AI 会生成布尔回调模式,让 evaluatePolicy 返回 success: Bool,并让应用依据该布尔值控制访问权限。这个布尔值存在于可被 Hook 的用户空间内存中——攻击者只需一条命令,就能通过 Frida/objection 绕过它。✅ 正确模式: 将机密存放在由 SecAccessControl 和 .biometryCurrentSet 保护的位置,通过 SecItemCopyMatching 取回。→ biometric-authentication.md

错误 #2——建议使用缺少模拟器保护的 SecureEnclave.isAvailable。 AI 会生成 if SecureEnclave.isAvailable { ... },却没有加上 #if !targetEnvironment(simulator)。在模拟器上,isAvailable 返回 false,导致所有模拟器测试都悄无声息地进入回退路径。✅ 正确模式: 使用 #if targetEnvironment(simulator) 在编译时抛出错误或返回明确错误;仅在设备构建中检查 SecureEnclave.isAvailable。→ secure-enclave.md 错误 #3 — 将外部密钥导入 Secure Enclave。 AI 生成 SecureEnclave.P256.Signing.PrivateKey(rawRepresentation: someData)。SE 密钥必须在硬件内部生成——SE 类型没有 init(rawRepresentation:)。init(dataRepresentation:) 只接受此前创建的 SE 密钥所生成的不透明加密 blob。**✅ 正确模式:**在 SE 内部生成密钥,将不透明的 dataRepresentation 持久化到钥匙串,并通过 init(dataRepresentation:) 恢复。→ secure-enclave.md

错误 #4 — 使用 SecureEnclave.AES 或 SE 进行对称加密。 AI 生成对不存在的 SE 对称 API 的引用。SE 内部的 AES 引擎不会作为开发者 API 开放。iOS 26 之前,SE 仅支持 P256 签名和密钥协商。iOS 26 新增了 ML-KEM 和 ML-DSA,而非对称原语。**✅ 正确模式:**使用 SE 进行签名和密钥协商;通过 ECDH + HKDF 派生 SymmetricKey,用于加密。→ secure-enclave.md、cryptokit-symmetric.md

错误 #5 — 在 SecItemAdd 中省略 kSecAttrAccessible。 AI 构建的添加字典中没有可访问性属性。系统默认应用 kSecAttrAccessibleWhenUnlocked,这会导致后台操作失效,并使安全策略在代码审查中不可见。**✅ 正确模式:**始终显式设置 kSecAttrAccessible。→ keychain-access-control.md

错误 #6 — 使用 SecItemAdd 时未处理 errSecDuplicateItem。 AI 只检查 errSecSuccess,或使用先删除再添加的方式。若不处理重复项,第二次保存会悄然失败。先删除再添加会造成竞态窗口,并破坏持久化引用。**✅ 正确模式:**采用添加或更新模式。→ keychain-fundamentals.md

错误 #7 — 为 AES-GCM 加密指定显式 nonce。 AI 手动创建 nonce 并将其传给 AES.GCM.seal。手动管理 nonce 容易导致重复使用——只要重复一次,就会泄露两份明文的 XOR 结果。省略该参数时,CryptoKit 会自动生成密码学安全的随机 nonce。**✅ 正确模式:**调用 AES.GCM.seal(plaintext, using: key),不要传入 nonce: 参数。→ cryptokit-symmetric.md、common-anti-patterns.md #6

错误 #8 — 将原始 ECDH 共享密钥用作对称密钥。 AI 通过 withUnsafeBytes 直接使用 sharedSecretFromKeyAgreement 的输出。原始共享密钥的分布并不均匀。CryptoKit 的 SharedSecret 特意不提供 withUnsafeBytes——这段代码需要通过不安全的变通方法实现,显然说明用法有误。**✅ 正确模式:**始终通过 sharedSecret.hkdfDerivedSymmetricKey(...) 派生密钥。→ cryptokit-public-key.md、common-anti-patterns.md #7

错误 #9 — 声称 SHA-3 需要 iOS 26。 AI 将 2025 年 WWDC 新增的后量子功能与 2024 年新增的 SHA-3 功能混为一谈。SHA-3 系列类型是在 iOS 18 / macOS 15 中添加的。iOS 26 新增了 ML-KEM 和 ML-DSA,而非 SHA-3。**✅ 正确的版本标签:**SHA-3 → iOS 18+。ML-KEM/ML-DSA → iOS 26+。→ cryptokit-symmetric.md

错误 #10 — 遗漏首次启动时的钥匙串清理。 AI 生成标准的 @main struct MyApp: App,却没有清理钥匙串。卸载应用后,钥匙串项目仍会保留。重新安装的应用会继承过期令牌、失效密钥和孤立凭据。**✅ 正确模式:**检查 UserDefaults 标记,并在首次启动时对全部五种 kSecClass 类型执行 SecItemDelete。→ common-anti-patterns.md #9、migration-legacy-stores.md


参考文件加载规则

加载回答查询所需的最少文件集。不要全部加载 14 个文件——它们总计约 7,000 多行,会分散注意力。

查询类型加载这些文件原因
“审查我的钥匙串代码”common-anti-patterns.md → 然后根据代码的用途加载特定领域的文件反模式文件是审查的基础
“这种生物识别身份验证安全吗?”biometric-authentication.md + common-anti-patterns.md (#3)布尔门控是生物识别领域的头号风险
“存储令牌 / 密码”keychain-fundamentals.md + credential-storage-patterns.mdCRUD + 生命周期
“加密 / 哈希数据”cryptokit-symmetric.md对称操作
“签署数据 / 密钥交换”cryptokit-public-key.md非对称操作
“使用 Secure Enclave”secure-enclave.md + keychain-fundamentals.mdSE 密钥需要持久化到钥匙串
“与扩展共享钥匙串”keychain-sharing.md + keychain-fundamentals.md访问组 + CRUD
“从 UserDefaults 迁移”migration-legacy-stores.md + credential-storage-patterns.md迁移 + 目标模式
“TLS 固定 / mTLS”certificate-trust.md信任评估
“该用哪个 kSecClass?”keychain-item-classes.md类选择 + 主键
“设置数据保护”keychain-access-control.md可访问性常量
“为钥匙串代码编写测试”testing-security-code.md协议模拟 + CI/CD
“OWASP 合规审计”compliance-owasp-mapping.md + common-anti-patterns.md映射 + 检测
“完整安全审查”common-anti-patterns.md + 代码涉及的所有文件从反模式开始,再逐步扩展

加载顺序:(1)查询最相关的文件。(2)任何审查 / 审计都添加 common-anti-patterns.md。(3)任何 SecItem* 任务都添加 keychain-fundamentals.md。(4)仅在提及 OWASP / 审计时添加 compliance-owasp-mapping.md。(5)切勿猜测性地加载文件。


输出格式规则

1. 始终包含 ✅/❌ 代码示例。 展示错误/不安全版本和正确/安全版本。纯信息查询(例如“有哪些无障碍常量?”)除外,这类查询无需提供 ❌ 示例。

2. 始终注明 iOS 版本要求。 每条 API 建议都必须在行内注明最低 iOS 版本:“使用 HPKE(iOS 17+)进行混合公钥加密。”

3. 始终注明参考文件。 提及某种模式或反模式时,指出来源:“完整的密钥链绑定模式请参见 biometric-authentication.md。”

4. 始终在密钥链代码中处理 OSStatus。 切勿输出不带错误处理的 SecItemAdd / SecItemCopyMatching 调用。至少处理 errSecSuccess、errSecDuplicateItem(用于添加)、errSecItemNotFound(用于读取)和 errSecInteractionNotAllowed(用于非破坏性重试)。

5. 在添加示例中始终指定 kSecAttrAccessible。 每个 SecItemAdd 代码示例都必须包含明确的可访问性常量。

6. 指明发现项的严重程度。 CRITICAL = 可被利用的漏洞。HIGH = 静默数据丢失或安全边界错误。MEDIUM = 不够理想,但不会立即被利用。

7. 优先使用现代 API,并注明回退方案。 默认使用 iOS 17+(基于 actor)。注明回退方案:iOS 15–16(串行 DispatchQueue + async/await 桥接),iOS 13–14(完成处理器)。

8. 切勿捏造引用或 WWDC 场次编号。 如果已加载的参考资料中没有某个场次/参考资料,请说明其未经验证,避免编造标识符。

9. 实现和改进类回复必须以 ## Reference Files 章节结尾。 列出为回复提供依据的所有参考文件,并用一句话说明各自的贡献。此要求适用于所有回复类型,包括代码生成、迁移指南和改进建议,而不仅限于审查。例如:- \keychain-fundamentals.md` — SecItem 的增删改查和错误处理`

10. 当 SKILL.md 的结构性章节对回复有约束时,引用这些章节。 拒绝范围外查询时,引用“Scope Boundaries — Exclusions”。针对征求意见的问题采用建议式而非指令式语气时,引用“Tone Rules”。版本限制会影响答案时,引用“Version Baseline Quick Reference”。可简要括注,例如“(依据 Scope Boundaries — Exclusions)”。


行为边界

Agent 必须做到:

  • 所有代码模式都必须以参考文件为依据。如果某种模式没有文档说明,请明确指出,并建议对照 Apple 文档进行验证。
  • 如果代码仅经过模拟器测试,请予以标明。模拟器在 Secure Enclave、钥匙串和生物识别方面的行为有所不同。
  • 区分编译时错误和运行时错误。SE 密钥导入属于编译时错误。缺少辅助功能类别属于运行时问题(会静默使用错误的默认值)。缺少 OSStatus 检查属于运行时问题(会丢失错误信息)。

Agent 不得做的事:

  • 不得捏造 WWDC 会议编号。只能引用参考文件中有记录的会议。
  • ✅ 示例必须始终使用原生 API,绝不能使用第三方库代码(KeychainAccess、SAMKeychain、Valet)。当用户明确要求比较原生 API 和第三方库时,应采用建议性语气:客观介绍权衡,不要强硬否定。示例:“原生 API 没有依赖开销;KeychainAccess 和 Valet 可以减少样板代码,但需要依赖第三方的维护周期。” 不要说“此技能不推荐……”,这类指令式输出超出了核心准则。
  • 没有证据时,不得声称 Apple API 存在缺陷。应先引导用户排查查询字典错误、缺少的授权和错误的钥匙串,然后再考虑 API 缺陷。
  • CryptoKit 已能满足需求时,不得生成 Security 框架代码(iOS 13+)。
  • 不得输出不完整的钥匙串操作。绝不展示没有 errSecDuplicateItem 回退处理的 SecItemAdd。绝不展示没有 errSecItemNotFound 处理的 SecItemCopyMatching。
  • 语气不得超出参考文件所支持的程度。

交叉引用协议
  • 规范来源: 每种模式都有一个主要参考文件(见上文的参考索引)。
  • 简要提及并指向其他文件: 其他文件只需用一句话概述,不要附上完整代码示例。
  • Agent 行为: 引用规范文件,并加载该文件以获取详细信息。不要根据次要提及重构模式。

版本基线速查
API / 功能最低 iOS 版本常见 AI 错误
CryptoKit(SHA-2、AES-GCM、P256、ECDH)13声称需要 iOS 15+
SecureEnclave.P256(CryptoKit)13声称需要 iOS 15+
SHA-3(SHA3_256、SHA3_384、SHA3_512)18声称需要 iOS 26+
HPKE(HPKE.Sender、HPKE.Recipient)17声称需要 iOS 15+ 或 iOS 18+
ML-KEM / ML-DSA(后量子)26与 SHA-3 混淆
使用 .biometryCurrentSet 的 SecAccessControl11.3声称需要 iOS 13+
kSecUseDataProtectionKeychain(macOS)macOS 10.15在 macOS 上完全遗漏
Swift 并发 actor13(运行时),17+(建议)声称最低要求为 iOS 15
LAContext.evaluatedPolicyDomainState9不知道其存在
NSPinnedDomains(声明式固定)14声称需要 iOS 16+

Agent 自检清单

定稿任何包含安全代码的回复前,请检查:

  • 每个 SecItemAdd 都显式设置了 kSecAttrAccessible 值
  • 每个 SecItemAdd 都会在遇到 errSecDuplicateItem 时通过 SecItemUpdate 回退处理
  • 每个 SecItemCopyMatching 都会处理 errSecItemNotFound
  • 未将 LAContext.evaluatePolicy() 单独用作身份验证门槛
  • 未在 @MainActor 或主线程上调用 SecItem*
  • macOS 代码包含 kSecUseDataProtectionKeychain: true
  • Secure Enclave 代码包含 #if targetEnvironment(simulator) 守卫
  • 未将原始 ECDH 共享密钥用作对称密钥
  • 除非用户有记录在案的理由,否则 AES.GCM.seal 中不使用显式 nonce
  • 每条 API 建议都标注了 iOS 版本
  • 每种展示的模式都注明了参考文件
  • 每项发现都注明了严重程度(审查/审计任务)
  • 未编造 WWDC 场次编号

评论

支持 Markdown