美文网首页
Swift5.0 实现HTTPS双向认证

Swift5.0 实现HTTPS双向认证

作者: 左方 | 来源:发表于2021-07-19 13:32 被阅读0次

    网络请求库使用Alamofire

    class ABCSessionDelegate: SessionDelegate {
        override func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
            switch challenge.protectionSpace.authenticationMethod {
            case NSURLAuthenticationMethodClientCertificate:
                guard let file = Bundle.main.path(forResource: "公钥文件名", ofType: "p12"),
                      let p12Data = try? Data.init(contentsOf: URL.init(fileURLWithPath: file)!) else {
                    
                    completionHandler(.performDefaultHandling, nil)
                    return
                }
                
                let p12Contents = PKCS12(pkcs12Data: p12Data, password: "公钥密码")
                guard let identity = p12Contents.identity else {
                    completionHandler(.performDefaultHandling, nil)
                    return
                }
                
                let credential = URLCredential(identity: identity,
                                               certificates: nil,
                                               persistence: .none)
                challenge.sender?.use(credential, for: challenge)
                completionHandler(.useCredential, credential)
            default:
                completionHandler(.performDefaultHandling, nil)
            }
        }
        
        private class PKCS12 {
            let label: String?
            let keyID: NSData?
            let trust: SecTrust?
            let certChain: [SecTrust]?
            let identity: SecIdentity?
            
            /// Creates a PKCS12 instance from a piece of data.
            /// - Parameters:
            ///   - pkcs12Data: the actual data we want to parse.
            ///   - password: The password required to unlock the PKCS12 data.
            public init(pkcs12Data: Data, password: String) {
                let importPasswordOption: NSDictionary
                    = [kSecImportExportPassphrase as NSString: password]
                var items: CFArray?
                let secError: OSStatus
                    = SecPKCS12Import(pkcs12Data as NSData,
                                      importPasswordOption, &items)
                guard secError == errSecSuccess else {
                    if secError == errSecAuthFailed {
                        NSLog("Incorrect password?")
                        
                    }
                    fatalError("Error trying to import PKCS12 data")
                }
                guard let theItemsCFArray = items else { fatalError() }
                let theItemsNSArray: NSArray = theItemsCFArray as NSArray
                guard let dictArray
                        = theItemsNSArray as? [[String: AnyObject]] else {
                    fatalError()
                }
                func f<T>(key: CFString) -> T? {
                    for dict in dictArray {
                        if let value = dict[key as String] as? T {
                            return value
                        }
                    }
                    return nil
                }
                self.label = f(key: kSecImportItemLabel)
                self.keyID = f(key: kSecImportItemKeyID)
                self.trust = f(key: kSecImportItemTrust)
                self.certChain = f(key: kSecImportItemCertChain)
                self.identity = f(key: kSecImportItemIdentity)
            }
        }
    }
    

    使用

    class ABCRequest {
    lazy var session : Session = {
            // 验证服务器的公钥
            // 默认获取了 cer 结尾的文件,不需要显示指定
            let trustManager = ServerTrustManager(evaluators: [
                M_NodeServerUrl: PublicKeysTrustEvaluator()
            ])
            return Session(delegate: WSSessionDelegate(),
                           serverTrustManager: trustManager)
        }()
    
    
    session.request(url,
                            method: .post,
                            parameters: parameters,
                            encoding: URLEncoding.default,
                            headers: HTTPheaders,
                            interceptor: interceptor,
                            requestModifier: requestModifier)
    
    
    }
    

    参考资料:https://leenarts.net/2020/02/28/client-certificate-with-urlsession-in-swift/

    相关文章

      网友评论

          本文标题:Swift5.0 实现HTTPS双向认证

          本文链接:https://www.haomeiwen.com/subject/fbocmltx.html