Swift开发进阶AlamofireiOS 进阶开发

Alamofire(7)— 安全认证

2019-09-20  本文已影响0人  Cooci_和谐学习_不急不躁

😊😊😊Alamofire专题目录,欢迎及时反馈交流 😊😊😊


Alamofire 目录直通车 --- 和谐学习,不急不躁!


这个篇章会介绍 http 安全认证相关知识!http 提供了一系列的技术和机器,可用来跟踪身份,进行安全性检测,控制对内容的访问。通过这一篇文章你会对知道为什么https如此重要。同时也会介绍 Alamofire 关于安全认证的处理

HTTP特点

正是因为这些特点,也造就了灵活的http 存在很多问题

对称加密&非对称加密

例子:假如有 ClientServer 之间要进行通讯,他们商定了一种秘钥Client 用秘钥加密传输信息。Server 收到信息用秘钥解密信息。这样的一个通信过程就是对称加密的过程。

缺点:对称加密的缺点就在于如果秘钥要是泄露,这样Client与Server之间的信息传递就不安全了

例子:假如有ClientA、ClientB、ClientC与Server进行通讯,Server拥有一对公钥和私钥,它自己保留唯一的私钥,对外公开自己的公钥,这样 ClientA、ClientB、ClientC 都能拿到公钥。ClientA 用公钥加密的密文只有 Server 的私钥才能解密,这样 ClientA 传递信息就是安全的了,因为即使有中间黑客获取了公钥加密的密文,因为黑客没有私钥也没有办法解密。

缺点:非对称加密只是保证了Client向Server发送的消息是安全的,因为私钥有且只有一把在Server手中,但是反过来Server向Client发送的消息就不是安全的,因为公钥是公开的大家都能下载,也就都能解密信息。

HTTPS安全传输

超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为 HTTP over TLSHTTP over SSLHTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。

加密过程

可以看到工作流程,基本分为三个阶段:

Alamofire安全传输

下面我们开始自签证书验证处理

1️⃣: 配置自签证书信息

fileprivate func lgtrustSession() -> SessionManager{
    
    let policies: [String:ServerTrustPolicy] = [
        hostUrl1: .pinCertificates(
            certificates: ServerTrustPolicy.certificates(),
            validateCertificateChain: false,
            validateHost: true),
        hostUrl2: .disableEvaluation,
        hostUrl3: .pinPublicKeys(
            publicKeys: ServerTrustPolicy.publicKeys(),
            validateCertificateChain: false,
            validateHost: true)
    ]
    
    let sesionManager = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies))
    return sesionManager
}

Alamofire 安全认证策略的六种模式,其中最常用的有这三种:.pinCertificates 证书验证模式、.pinPublicKeys 公钥验证模式和 .disableEvaluation 不验证模式。

2️⃣:证书与公钥信息获取

其中这里笔者采用的遍历整个工程 bundle 获取证书

public static func certificates(in bundle: Bundle = Bundle.main) -> [SecCertificate] {
    var certificates: [SecCertificate] = []

    let paths = Set([".cer", ".CER", ".crt", ".CRT", ".der", ".DER"].map { fileExtension in
        bundle.paths(forResourcesOfType: fileExtension, inDirectory: nil)
    }.joined())

    for path in paths {
        if
            let certificateData = try? Data(contentsOf: URL(fileURLWithPath: path)) as CFData,
            let certificate = SecCertificateCreateWithData(nil, certificateData)
        {
            certificates.append(certificate)
        }
    }
    return certificates
}
public static func publicKeys(in bundle: Bundle = Bundle.main) -> [SecKey] {
    var publicKeys: [SecKey] = []

    for certificate in certificates(in: bundle) {
        if let publicKey = publicKey(for: certificate) {
            publicKeys.append(publicKey)
        }
    }
    return publicKeys
}

3️⃣:接受质询

urlSession(
        _ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
// realm是ProtectionSpace的标示符,
//服务器上的一组资源通过realm来标示成一组采用相同验证方式的资源(ProtectionSpace)。
open var realm: String? { get }
// 确定此保护空间的密码是否可以安全地发送
open var receivesCredentialSecurely: Bool { get }
// 资源所在的服务器
open var host: String { get }
// 资源所在服务器端口
open var port: Int { get }
// 如果是代理,则获取此保护空间的类型
open var proxyType: String? { get }
//获取资源的协议资源
open var `protocol`: String? { get }
// 质询所采用验证方式
open var authenticationMethod: String { get }

质询验证方式有如下几种是常用的

UrlCredential

他是客户端对服务器端质询的响应。根据验证方式不一样,有如下几种UrlCredential:

SecTrust

下面具体代码分析

if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
    let host = challenge.protectionSpace.host
    // 返回与给定主机完全匹配的策略
    if
        let serverTrustPolicy = session.serverTrustPolicyManager?.serverTrustPolicy(forHost: host),
        // 返回一个SecTrustRef,它表示服务器SSL事务状态的状态
        let serverTrust = challenge.protectionSpace.serverTrust
    {
        // 评估服务器信任是否对给定主机有效。
        if serverTrustPolicy.evaluate(serverTrust, forHost: host) {
            disposition = .useCredential
            credential = URLCredential(trust: serverTrust)
        } else {
            disposition = .cancelAuthenticationChallenge
        }
    }
}

验证方法:public func evaluate(_ serverTrust: SecTrust, forHost host: String) -> Bool

这里同时也给大家提供一篇专业介绍 证书链的文章

4️⃣:证书完毕,就可以直接正常通讯了!

总结

这一篇关于 安全认证 的文章涉及到了 http以及https 各自的特点,还有加密手段,最后分析了 Alamofire安全认证,过程看是复杂,其实就是一个证书或者公钥匹配问题,但是这些也是很多iOS开发人员经常不愿去涉猎的地方,知识点枯燥难懂!但是:而世之奇伟,瑰鬼,非常之观,常在于险远,而人之所罕至焉,故非有志着不能至也。iOS中高级进阶没有其他,就是沉下心来,认真打磨自己!💪💪💪

下一篇开始介绍面向协议编程板块,最后非常感谢大家一路的关注!

就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!

上一篇下一篇

猜你喜欢

热点阅读