iOS开发 - swift通过Alamofire实现https通信

简介: iOS开发 - swift通过Alamofire实现https通信

https相关

先推荐博主用OC实现的https通信:

iOS开发 - 用AFNetworking实现https单向验证,双向验证

http://blog.csdn.net/codingfire/article/details/53419521


本文信息来源于http://www.hangge.com/blog/cache/detail_1052.html,不错的一个网址。


实现了OC的https,那么swift的https怎么来写呢,实际上,两者实现没有什么差别,只是对应代码转化成swift的模式,偶然想到这个问题,但是又懒得自己去写,所以在网上找了下,于是发现了上面的网址,swift通过Alamofire实现https,由于之前遇到太多垃圾代码,为了保证这里的代码切实可行,遂通过实战来进行检验:

https双向验证:

import UIKit
import Alamofire
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        //认证相关设置
        let manager = SessionManager.default
        manager.delegate.sessionDidReceiveChallenge = { session, challenge in
            //认证服务器证书
            if challenge.protectionSpace.authenticationMethod
                == NSURLAuthenticationMethodServerTrust {
                print("服务端证书认证!")
                let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
                let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
                let remoteCertificateData
                    = CFBridgingRetain(SecCertificateCopyData(certificate))!
                let cerPath = Bundle.main.path(forResource: "server", ofType: "cer")!
                let cerUrl = URL(fileURLWithPath:cerPath)
                let localCertificateData = try! Data(contentsOf: cerUrl)
                if (remoteCertificateData.isEqual(localCertificateData) == true) {
                    let credential = URLCredential(trust: serverTrust)
                    challenge.sender?.use(credential, for: challenge)
                    return (URLSession.AuthChallengeDisposition.useCredential,
                            URLCredential(trust: challenge.protectionSpace.serverTrust!))
                } else {
                    return (.cancelAuthenticationChallenge, nil)
                }
            }
                //认证客户端证书
            else if challenge.protectionSpace.authenticationMethod
                == NSURLAuthenticationMethodClientCertificate {
                print("客户端证书认证!")
                //获取客户端证书相关信息
                let identityAndTrust:IdentityAndTrust = self.extractIdentity();
                let urlCredential:URLCredential = URLCredential(
                    identity: identityAndTrust.identityRef,
                    certificates: identityAndTrust.certArray as? [AnyObject],
                    persistence: URLCredential.Persistence.forSession);
                return (.useCredential, urlCredential);
            }
                // 其它情况(不接受认证)
            else {
                print("其它情况(不接受认证)")
                return (.cancelAuthenticationChallenge, nil)
            }
        }
        //数据请求
        Alamofire.request("请求地址")
            .responseString { response in
                print(response)
        }
    }
    //获取客户端证书相关信息
    func extractIdentity() -> IdentityAndTrust {
        var identityAndTrust:IdentityAndTrust!
        var securityError:OSStatus = errSecSuccess
        let path: String = Bundle.main.path(forResource: "client", ofType: "p12")!
        let PKCS12Data = NSData(contentsOfFile:path)!
        let key : NSString = kSecImportExportPassphrase as NSString
        let options : NSDictionary = [key : "xxxxxxxxxxx"] //客户端证书密码
        //create variable for holding security information
        //var privateKeyRef: SecKeyRef? = nil
        var items : CFArray?
        securityError = SecPKCS12Import(PKCS12Data, options, &items)
        if securityError == errSecSuccess {
            let certItems:CFArray = items as CFArray!;
            let certItemsArray:Array = certItems as Array
            let dict:AnyObject? = certItemsArray.first;
            if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
                // grab the identity
                let identityPointer:AnyObject? = certEntry["identity"];
                let secIdentityRef:SecIdentity = identityPointer as! SecIdentity!
                print("\(identityPointer)  :::: \(secIdentityRef)")
                // grab the trust
                let trustPointer:AnyObject? = certEntry["trust"]
                let trustRef:SecTrust = trustPointer as! SecTrust
                print("\(trustPointer)  :::: \(trustRef)")
                // grab the cert
                let chainPointer:AnyObject? = certEntry["chain"]
                identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef,
                                                    trust: trustRef, certArray:  chainPointer!)
            }
        }
        return identityAndTrust;
    }
//定义一个结构体,存储认证相关信息
struct IdentityAndTrust {
    var identityRef:SecIdentity
    var trust:SecTrust
    var certArray:AnyObject
}
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

接着需要配置plist,这里的配置和OC是一样的:

1.png

配置好之后运行项目,可拿到请求结果。

Demo下载放在最后!


https单向验证,验证服务器通过服务器的域名和IP地址来验证,服务器验证客户端证书和密码:

import UIKit
import Alamofire
class ViewController: UIViewController {
    //自签名网站地址
    let selfSignedHosts = ["域名","IP地址"]
    override func viewDidLoad() {
        super.viewDidLoad()
        //认证相关设置
        let manager = SessionManager.default
        manager.delegate.sessionDidReceiveChallenge = { session, challenge in
            //认证服务器(这里不使用服务器证书认证,只需地址是我们定义的几个地址即可信任)
            if challenge.protectionSpace.authenticationMethod
                == NSURLAuthenticationMethodServerTrust
                && self.selfSignedHosts.contains(challenge.protectionSpace.host) {
                print("服务器认证!")
                let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
                return (.useCredential, credential)
            }
                //认证客户端证书
            else if challenge.protectionSpace.authenticationMethod
                == NSURLAuthenticationMethodClientCertificate {
                print("客户端证书认证!")
                //获取客户端证书相关信息
                let identityAndTrust:IdentityAndTrust = self.extractIdentity();
                let urlCredential:URLCredential = URLCredential(
                    identity: identityAndTrust.identityRef,
                    certificates: identityAndTrust.certArray as? [AnyObject],
                    persistence: URLCredential.Persistence.forSession);
                return (.useCredential, urlCredential);
            }
                // 其它情况(不接受认证)
            else {
                print("其它情况(不接受认证)")
                return (.cancelAuthenticationChallenge, nil)
            }
        }
        //数据请求
        Alamofire.request("https://xxxxxxxxx")
            .responseString { response in
                print(response)
        }
    }
    //获取客户端证书相关信息
    func extractIdentity() -> IdentityAndTrust {
        var identityAndTrust:IdentityAndTrust!
        var securityError:OSStatus = errSecSuccess
        let path: String = Bundle.main.path(forResource: "client", ofType: "p12")!
        let PKCS12Data = NSData(contentsOfFile:path)!
        let key : NSString = kSecImportExportPassphrase as NSString
        let options : NSDictionary = [key : "xxxxxxxxxxx"] //客户端证书密码
        //create variable for holding security information
        //var privateKeyRef: SecKeyRef? = nil
        var items : CFArray?
        securityError = SecPKCS12Import(PKCS12Data, options, &items)
        if securityError == errSecSuccess {
            let certItems:CFArray = items as CFArray!;
            let certItemsArray:Array = certItems as Array
            let dict:AnyObject? = certItemsArray.first;
            if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
                // grab the identity
                let identityPointer:AnyObject? = certEntry["identity"];
                let secIdentityRef:SecIdentity = identityPointer as! SecIdentity!
                print("\(identityPointer)  :::: \(secIdentityRef)")
                // grab the trust
                let trustPointer:AnyObject? = certEntry["trust"]
                let trustRef:SecTrust = trustPointer as! SecTrust
                print("\(trustPointer)  :::: \(trustRef)")
                // grab the cert
                let chainPointer:AnyObject? = certEntry["chain"]
                identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef,
                                                    trust: trustRef, certArray:  chainPointer!)
            }
        }
        return identityAndTrust;
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
//定义一个结构体,存储认证相关信息
struct IdentityAndTrust {
    var identityRef:SecIdentity
    var trust:SecTrust
    var certArray:AnyObject
}

同样,这里也需要配置plist,和上面双向验证是一样的。而下面这样也是可以的。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

最后下载Demo福利,因为证书密钥等等属于机密,所以博主删除了,倒入自己的即可。

双向认证下载

单向认证下载

目录
相关文章
|
6月前
|
运维 安全 网络安全
443端口:HTTPS通信的安全基石
作为互联网安全的基石,443端口通过加密与认证机制,保护了数十亿用户的隐私与数据完整性。无论是开发者、运维人员还是普通用户,理解其原理与作用都至关重要。在享受便利的同时,也需时刻关注安全实践,防范潜在风险。
1725 12
|
10月前
|
iOS开发 开发者
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
626 67
uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
|
9月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
395 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
11月前
|
iOS开发 开发者 MacOS
深入探索iOS开发中的SwiftUI框架
【10月更文挑战第21天】 本文将带领读者深入了解Apple最新推出的SwiftUI框架,这一革命性的用户界面构建工具为iOS开发者提供了一种声明式、高效且直观的方式来创建复杂的用户界面。通过分析SwiftUI的核心概念、主要特性以及在实际项目中的应用示例,我们将展示如何利用SwiftUI简化UI代码,提高开发效率,并保持应用程序的高性能和响应性。无论你是iOS开发的新手还是有经验的开发者,本文都将为你提供宝贵的见解和实用的指导。
329 66
|
9月前
|
人工智能 程序员 API
iOS|记一名 iOS 开发新手的前两次 App 审核经历
啥,这玩意也有新手保护期?
261 0
|
11月前
|
存储 监控 API
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
app开发之安卓Android+苹果ios打包所有权限对应解释列表【长期更新】-以及默认打包自动添加权限列表和简化后的基本打包权限列表以uniapp为例-优雅草央千澈
1104 11
|
12月前
|
安全 搜索推荐 网络安全
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
352 11
|
11月前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。
349 3
|
11月前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
12月前
|
存储 前端开发 Swift
探索iOS开发:从新手到专家的旅程
本文将带您领略iOS开发的奇妙之旅,从基础概念的理解到高级技巧的掌握,逐步深入iOS的世界。文章不仅分享技术知识,还鼓励读者在编程之路上保持好奇心和创新精神,实现个人成长与技术突破。

相关课程

更多