You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:35:24