iOS 使用pfx证书签名和验签

为了数据的安全传输,最近在搞证书的签名和验签需求,证书给的是pfx,由于这方便的资料太少,在这里记录一下。
使用的是Swift中的Security框架

读取pfx证书, 签名和验签都要使用

func readPfxFile(path: String, password: String) -> SecIdentity? {
        var identity: SecIdentity?
        let fileURL = URL(fileURLWithPath: path)
        let data = try? Data(contentsOf: fileURL)
        
        if let data = data {
            let options: [CFString: Any] = [kSecImportExportPassphrase: password]
            var importResult: CFArray?
            
            let status = SecPKCS12Import(data as CFData, options as CFDictionary, &importResult)
            
            if status == errSecSuccess, let items = importResult as? [AnyObject]{
                let identityItem = items[0]
                
                guard let cfIdentity = identityItem.value(forKey: kSecImportItemIdentity as String) as CFTypeRef?,
                    CFGetTypeID(cfIdentity) == SecIdentityGetTypeID() else {
                        return nil
                }
                identity = (cfIdentity as! SecIdentity)
            }
        }
        
        return identity
    }

提取私钥,签名

func signText(plainText: String, path: String, password: String) -> String? {
        guard let identity = readPfxFile(path: path, password: password) else {
            print("signText: SecIdentity is empty")
            return nil
        }
        
        var aPrivateKey: SecKey?
        let status = SecIdentityCopyPrivateKey(identity, &aPrivateKey)
        if status != errSecSuccess {
            print("signText: SecIdentityCopyPrivateKey error")
            return nil
        }
        
        guard let privateKey = aPrivateKey else {
            print("signText: privateKey is empty")
            return nil
        }
        
        guard let plainData = plainText.data(using: .utf8) else {
            print("signText: plainData is empty")
            return nil
        }
        
        guard let resultData = SecKeyCreateSignature(privateKey, SecKeyAlgorithm.rsaSignatureMessagePKCS1v15SHA256, plainData as CFData, nil) else {
            print("signText: resultData is empty")
            return nil
        }
        
        let result = (resultData as Data).base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
        return result
    }

提取公钥,验签

func verifySign(plainText: String, signature: String, path: String, password: String) {
        guard let identity = readPfxFile(path: path, password: password) else {
            print("verifySign: SecIdentity is empty")
            return
        }
        
        var optCertificateRef : SecCertificate?
        let secError = SecIdentityCopyCertificate(identity, &optCertificateRef)
        guard secError == errSecSuccess, let certificate = optCertificateRef else {
            print("verifySign: certificate is empty")
            return
        }
        
        var aTrust: SecTrust?
        let x509 = SecPolicyCreateBasicX509()
        
        SecTrustCreateWithCertificates(certificate, x509, &aTrust)
        
        guard let trust = aTrust else {
            print("verifySign: trust is empty")
            return
        }
        
        guard let publicKey = SecTrustCopyPublicKey(trust) else {
            print("verifySign: publicKey is empty")
            return
        }
        
        guard let plainData = plainText.data(using: .utf8) else {
            print("verifySign: plainData is empty")
            return
        }
        
        guard let signatureData = Data.init(base64Encoded: signature) else {
            print("verifySign: signatureData is empty")
            return
        }
        let result = SecKeyVerifySignature(publicKey, SecKeyAlgorithm.rsaSignatureMessagePKCS1v15SHA256, plainData as CFData, signatureData as CFData, nil)
        print(result)
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容