MacOS Swift中Keychain API仅查询系统钥匙串不检索登录钥匙串问题
问题根因
你当前的查询没有指定钥匙串搜索范围,MacOS的Security框架默认查询范围受应用沙箱权限限制,默认仅查询system.keychain,不会主动包含login.keychain。
修复方案
1. 核心修复逻辑
通过kSecMatchSearchList键指定要查询的钥匙串列表,同时包含login和system钥匙串即可覆盖两个存储位置的证书查询。
2. 完整修改后的代码
import Security func isKeychainhasCert(for sNumber:Data) -> Bool { // 先获取login和system钥匙串的引用 var loginKeychain: SecKeychain? var systemKeychain: SecKeychain? // 兼容新旧版本login钥匙串路径 let loginPaths = ["~/Library/Keychains/login.keychain-db", "~/Library/Keychains/login.keychain"] for path in loginPaths { let expandedPath = (path as NSString).expandingTildeInPath if SecKeychainOpen(expandedPath, &loginKeychain) == errSecSuccess { break } } // 获取system钥匙串引用 SecKeychainOpen("/Library/Keychains/System.keychain", &systemKeychain) var searchList: [SecKeychain] = [] if let login = loginKeychain { searchList.append(login) } if let system = systemKeychain { searchList.append(system) } var query = [String: AnyObject]() query[kSecClass as String] = kSecClassCertificate query[kSecAttrSerialNumber as String] = sNumber as CFData query[kSecReturnRef as String] = true as CFBoolean // 指定搜索的钥匙串列表 if !searchList.isEmpty { query[kSecMatchSearchList as String] = searchList as CFArray } var queryResult: AnyObject? let status = withUnsafeMutablePointer(to: &queryResult, { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }) guard status != errSecItemNotFound else { return false } return true }
3. 权限配置注意事项
- 非沙箱应用无需额外配置,首次查询时系统会弹出授权提示,用户允许后即可正常读取login钥匙串内容
- 沙箱应用必须在Xcode项目的
Signing & Capabilities标签页开启Keychain Sharing权限,否则无法访问用户级别的login钥匙串 - 如果需要查询其他用户创建的自定义钥匙串,只需将对应钥匙串的路径加入搜索列表即可
内容的提问来源于stack exchange,提问作者kumar123
相关产品推荐
相关产品推荐

