iOS端Keychain使用kSecAttrKeyClassSymmetric时出现-25306错误
iOS Keychain 存储对称密钥报错-25306的解决办法
核心问题分析
错误码-25306(errKCNoSuchClass)的直接原因是kSecClass参数使用错误:
kSecAttrKeyClassSymmetric是kSecAttrKeyClass属性的取值,用于标记密钥为对称类型,它本身不是kSecClass的合法类值。- 要存储密钥类的Keychain项,
kSecClass必须设为kSecClassKey,再通过kSecAttrKeyClass指定具体的密钥类别。
另外,存储密钥类项时,还需要补充kSecAttrKeyType(密钥算法类型)、kSecAttrKeySizeInBits(密钥长度)等必要参数,否则会因参数不全导致操作失败。
修正后的Keychain工具类代码
final class KeychainHelper_SymmetricMethods { static let standard = KeychainHelper_SymmetricMethods() private init() {} /// 保存对称密钥到Keychain func saveSymmetricKey(_ data: Data, service: String, account: String) { // 注意:kSecClass必须为kSecClassKey,kSecAttrKeyClass指定对称密钥类型 let query: CFDictionary = [ kSecValueData: data, kSecClass: kSecClassKey, kSecAttrKeyClass: kSecAttrKeyClassSymmetric, kSecAttrKeyType: kSecAttrKeyTypeAES, // 根据实际密钥算法调整,示例用AES kSecAttrKeySizeInBits: 256, // 根据密钥长度调整,示例256位 kSecAttrService: service, kSecAttrAccount: account, kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked ] as CFDictionary let status = SecItemAdd(query, nil) if status == errSecDuplicateItem { let updateQuery: CFDictionary = [ kSecAttrService: service, kSecAttrAccount: account, kSecClass: kSecClassKey, kSecAttrKeyClass: kSecAttrKeyClassSymmetric ] as CFDictionary let attributesToUpdate: CFDictionary = [kSecValueData: data] as CFDictionary let updateStatus = SecItemUpdate(updateQuery, attributesToUpdate) print(updateStatus == errSecSuccess ? "密钥已覆盖更新" : "更新失败,错误码:\(updateStatus)") } else if status != errSecSuccess { print("保存失败,错误码:\(status)") } else { print("密钥保存成功") } } /// 读取Keychain中的对称密钥 func readSymmetricKey(service: String, account: String) -> Data? { let query: CFDictionary = [ kSecAttrService: service, kSecAttrAccount: account, kSecClass: kSecClassKey, kSecAttrKeyClass: kSecAttrKeyClassSymmetric, kSecReturnData: true, kSecMatchLimit: kSecMatchLimitOne ] as CFDictionary var result: AnyObject? let status = SecItemCopyMatching(query, &result) if status != errSecSuccess { print("读取失败,错误码:\(status)") } return result as? Data } /// 删除Keychain中的对称密钥 func deleteSymmetricKey(service: String, account: String) { let query: CFDictionary = [ kSecAttrService: service, kSecAttrAccount: account, kSecClass: kSecClassKey, kSecAttrKeyClass: kSecAttrKeyClassSymmetric ] as CFDictionary let status = SecItemDelete(query) print(status == errSecSuccess ? "密钥已删除" : "删除失败,错误码:\(status)") } }
关键参数说明
kSecClass:指定Keychain项的类别,存储密钥必须用kSecClassKey,而非密钥类型属性。kSecAttrKeyClass:仅当kSecClass为kSecClassKey时有效,用于区分对称密钥、非对称公钥/私钥。kSecAttrKeyType:指定密钥的算法类型,需和实际密钥算法匹配(比如AES对应kSecAttrKeyTypeAES)。kSecAttrKeySizeInBits:密钥的长度,比如256位AES就设为256。kSecAttrAccessible:控制密钥的访问权限时机,kSecAttrAccessibleWhenUnlocked是常用安全选项,确保设备解锁时才能访问,不是必须但建议设置。
使用示例
// 待保存的对称密钥数据 let stringToBeSaved = "c773c86d0e4a553349d329d6bb74e0a20dddc72f3f6b14f02258770bc879573d663d33f32167692fa1a2d1f85a9e51650956660f7398a94fce678c6c194d9ff1" guard let keyData = stringToBeSaved.data(using: .utf8) else { return } // 保存 KeychainHelper_SymmetricMethods.standard.saveSymmetricKey(keyData, service: "YourService", account: "YourAccount") // 读取 if let retrievedData = KeychainHelper_SymmetricMethods.standard.readSymmetricKey(service: "YourService", account: "YourAccount"), let retrievedString = String(data: retrievedData, encoding: .utf8) { print("读取到的密钥:\(retrievedString)") } // 删除 KeychainHelper_SymmetricMethods.standard.deleteSymmetricKey(service: "YourService", account: "YourAccount")
内容的提问来源于stack exchange,提问作者biggreentree
相关产品推荐
相关产品推荐

