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

如何验证证书是否成功添加至设备Keychain

验证iOS Keychain中证书是否成功导入

我正尝试将从API获取的证书导入设备Keychain,参考相关文章修改代码实现证书导入,代码如下:

func certificateFromCertificate(certP12: Data, psswd: String) {
    let decodedData =  certP12
    
    let keytmp : NSString = kSecImportExportPassphrase as NSString
    let options : NSDictionary = [keytmp : psswd]
    
    var certificateRef: SecCertificate? = nil
    
    var items : CFArray?
    
    let securityError: OSStatus = SecPKCS12Import(decodedData as CFData, options, &items)
    
    let theArray: CFArray = items!
    if securityError == noErr && CFArrayGetCount(theArray) > 0 {
        let newArray = theArray as [AnyObject] as NSArray
        let dictionary = newArray.object(at: 0)
        let secIdentity = (dictionary as AnyObject)[kSecImportItemIdentity as String] as! SecIdentity
        let securityError = SecIdentityCopyCertificate(secIdentity , &certificateRef)
        if securityError != noErr {
            certificateRef = nil
        }
    }
    
    var keychainQueryDictionary = [String : Any]()

    if let tempSecCert = certificateRef {
        keychainQueryDictionary = [kSecClass as String : kSecClassCertificate, kSecValueRef as String : tempSecCert, kSecAttrLabel as String: "My Certificate"]
    }

    let summary =  SecCertificateCopySubjectSummary(certificateRef!)!  as String
    print("Cert summary: \(summary)")

    let status = SecItemAdd(keychainQueryDictionary as CFDictionary, nil)

    print(SecCopyErrorMessageString(status, nil))
}

目前能获取到正确的证书摘要,且print(SecCopyErrorMessageString(status, nil))返回Optional(No error.),但不确定证书是否已正确安装至设备Keychain,且不想强制信任该证书,请问该如何验证?我尝试过以下代码,但仍需确认证书是否成功安装:

var keychainQueryDictionary = [String : Any]()

if let tempSecCert = certificateRef {
  keychainQueryDictionary = [kSecClass as String : kSecClassCertificate, kSecValueRef as String : tempSecCert, kSecAttrLabel as String: "My Certificate"]
}

let summary =  SecCertificateCopySubjectSummary(certificateRef!)!  as String
print("Cert summary: \(summary)")

let status = SecItemAdd(keychainQueryDictionary as CFDictionary, nil)

验证方法

1. 查询Keychain确认证书存在

构建查询语句从Keychain中搜索目标证书,验证是否能获取到结果:

func checkCertificateInKeychain(label: String) -> Bool {
    let query: [String: Any] = [
        kSecClass as String: kSecClassCertificate,
        kSecAttrLabel as String: label,
        kSecReturnRef as String: kCFBooleanTrue!,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    
    var item: CFTypeRef?
    let status = SecItemCopyMatching(query as CFDictionary, &item)
    
    if status == noErr, let _ = item as? SecCertificate {
        print("证书已存在于Keychain中")
        return true
    } else {
        print("证书未找到,错误信息:\(SecCopyErrorMessageString(status, nil) ?? "未知错误" as CFString)")
        return false
    }
}

// 使用示例
_ = checkCertificateInKeychain(label: "My Certificate")

2. 手动查看系统设置

在iOS设备的「设置」→「通用」→「VPN与设备管理」中,若证书已导入,会在对应列表中显示(注意:非CA根证书可能不会在这里展示,代码查询更准确)。

3. 验证证书可用性

尝试用证书进行基础操作,验证其是否能正常工作:

func verifyCertificateUsage(cert: SecCertificate) {
    var trust: SecTrust?
    let policy = SecPolicyCreateBasicX509()
    let status = SecTrustCreateWithCertificates(cert, policy, &trust)
    
    if status == noErr, let trust = trust {
        var trustResult: SecTrustResultType = .invalid
        let evalStatus = SecTrustEvaluate(trust, &trustResult)
        
        if evalStatus == noErr {
            switch trustResult {
            case .unspecified, .proceed:
                print("证书有效且可正常使用")
            case .denied, .invalid:
                print("证书无效或不被信任")
            default:
                print("证书信任状态未知")
            }
        }
    }
}

// 使用示例
if let cert = certificateRef {
    verifyCertificateUsage(cert: cert)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:55:57