macos 读取keychain中证书的方法

81 阅读1分钟
func loadCertificate(from filepath: String) -> SecCertificate? {
    do {
        // 读取证书文件内容到String
        let pemString = try String(contentsOfFile: filepath)
        
        let pattern = "-----BEGIN CERTIFICATE-----([\\s\\S]*)-----END CERTIFICATE-----"
        let regex = try NSRegularExpression(pattern: pattern)
        let nsRange = NSRange(pemString.startIndex..<pemString.endIndex, in: pemString)
        let matches = regex.matches(in: pemString, options: [], range: nsRange)
        
        guard let match = matches.first, match.numberOfRanges > 1 else {
            return nil
        }
        // 将编码中的\r\n都去掉
        var base64String = (pemString as NSString).substring(with: match.range(at: 1))
        base64String = base64String.replacingOccurrences(of: "\r\n", with: "")
        base64String = base64String.replacingOccurrences(of: "\n", with: "")
        // 将Base64字符串解码为Data
        guard let base64Data = Data(base64Encoded: base64String) else {
            return nil
        }

        guard let certificate = SecCertificateCreateWithData(nil, base64Data as CFData) else {
            return nil
        }
        return certificate
    } catch {
        return nil
    }
}
func certificateTrust() -> Bool {
    guard let path = Bundle.main.path(forResource: "xxx", ofType: "pem") else {
        return false
    }
    
    //读取证书文件
    guard let certOrigin = loadCertificate(from: path) else {
        return false
    }
    
    //读取颁发者信息
    guard let issuerData = SecCertificateCopyNormalizedIssuerSequence(certOrigin) else {
        return false
    }

    // 创建一个查询字典,用于描述我们想要查询的证书
    let query: [String: Any] = [
        kSecClass as String: kSecClassCertificate,
        kSecAttrIssuer as String: issuerData,
        kSecReturnRef as String: kCFBooleanTrue!,
        kSecMatchLimit as String: kSecMatchLimitAll
    ]

    // 从Keychain中查询证书
    var result: CFTypeRef?
    var status = SecItemCopyMatching(query as CFDictionary, &result)
    guard status == errSecSuccess, let item = result
    else
    {
        return false
    }
    if let certary = result as? [SecCertificate] {
    }
    
    //判断返回的类型是否是Certificate类型
    let typeId = CFGetTypeID(item)
    guard typeId == SecCertificateGetTypeID() else {
        return false
    }
    
    let certificate = item as! SecCertificate

    var trustResult: SecTrustResultType = .invalid
    var trust: SecTrust?
    let policy = SecPolicyCreateBasicX509()
    status = SecTrustCreateWithCertificates(certificate,policy, &trust)
    if status == errSecSuccess, let trustObject = trust
    {
        status = SecTrustEvaluate(trustObject, &trustResult)
    }
    else
    {
        return false
    }
    
    if status == errSecSuccess, trustResult == .proceed {
        return true
    }
    return false
}