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

如何不使用已弃用的SecKeychainCopyDomainDefault向System.keychain添加证书

解决MacOS 10.10+下获取系统钥匙串SecKeychainRef的非弃用方法

问题背景

自MacOS 10.10起,SecKeychainCopyDomainDefault已被弃用,但SecItemAdd的kSecUseKeychain键并未弃用,该键需要SecKeychainRef类型的值,目前找不到获取该值的非弃用方法。需求是将CA证书添加到System钥匙串,以下是原本以root身份运行可正常工作但依赖弃用API的代码:

SecKeychainRef system;
OSStatus keychainError = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem, &system);

CFDataRef data = CFDataCreate(kCFAllocatorDefault,  nsdataCert.bytes, nsdataCert.length);
SecCertificateRef test = SecCertificateCreateWithData(kCFAllocatorDefault, data);

const void *keys[] = { kSecClass, kSecAttrLabel, kSecValueRef, kSecUseKeychain};
const void *values[] = { kSecClassCertificate , @"Test Certificate", test, system};

CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 4, NULL, NULL);

int status = SecItemAdd ((CFDictionaryRef)query, NULL);
NSLog(@"status=%d", status);

非弃用解决方案

在MacOS 10.10及以上版本,可以直接通过系统钥匙串的默认路径,使用SecKeychainOpen API获取SecKeychainRef,系统钥匙串的默认路径为/Library/Keychains/System.keychain,修改后的代码如下:

NSString *systemKeychainPath = @"/Library/Keychains/System.keychain";
SecKeychainRef system;
OSStatus keychainError = SecKeychainOpen((CFStringRef)systemKeychainPath, &system);

if (keychainError == noErr) {
    CFDataRef data = CFDataCreate(kCFAllocatorDefault, nsdataCert.bytes, nsdataCert.length);
    SecCertificateRef test = SecCertificateCreateWithData(kCFAllocatorDefault, data);

    const void *keys[] = { kSecClass, kSecAttrLabel, kSecValueRef, kSecUseKeychain};
    const void *values[] = { kSecClassCertificate, @"Test Certificate", test, system};

    CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 4, NULL, NULL);

    int status = SecItemAdd((CFDictionaryRef)query, NULL);
    NSLog(@"status=%d", status);

    // 释放CF类型对象,避免内存泄漏
    CFRelease(query);
    CFRelease(test);
    CFRelease(data);
    CFRelease(system);
} else {
    NSLog(@"打开系统钥匙串失败: %d", keychainError);
}

注意事项

  • 操作仍需以root权限运行,系统钥匙串受系统保护,普通用户无写入权限。
  • 确认目标系统中/Library/Keychains/System.keychain路径存在,目前主流MacOS版本均沿用该路径。
  • 所有CF类型对象使用完毕后必须调用CFRelease释放,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Kyle Berezin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:15:40