Alamofire之安全认证

在网络如此发达的今天,网络安全已经和每一个人息息相关了。今天咱们就一块儿来了解一下网络安全方面的相关知识。算法

1、HTTPS简介

咱们知道,在HTTP协议中,发送的内容是以明文的形式传递的。这就致使了如下几个缺陷:swift

  • 明文内容,敏感数据容易被黑客窃听
  • 不对双方的身份做验证,容易被假装
  • 没法验证数据的完整性,数据容易被篡改

为了解决上面👆几个缺陷,苹果官方推荐使用HTTPS传输协议。浏览器

HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议。重要的是比HTTP更安全。安全

2、密码学基础

在了解HTTPS协议以前,咱们须要先有一点密码学基础。bash

明文:是指未被加密过的原始数据
复制代码
密文:明文被某个加密方式(算法)加密后,就变成了密文。密文能够被解密获得明文
复制代码
密钥:是在明文转换为密文的算法中所使用的参数。
密钥分为对称密钥和非对称密钥。分别对应对称加密和非对称加密。
复制代码
对称加密:对称加密又叫作私钥加密,即信息的发送方和接收方使用同一个密钥去加密和解密数据。
复制代码

对称加密的特色是算法公开、加密和解密速度快,适合于对大数据量进行加密。服务器

对称加密加密过程:明文 + 加密算法 + 私钥 => 密文 对称加密解密过程:密文 + 解密算法 + 私钥 => 明文网络

非对称加密:非对称加密也叫作公钥加密。非对称加密使用一对密钥,即公钥和私钥,且两者成对出现。用公钥或私钥中的任何一个进行加密,用另外一个进行解密。
复制代码

非对称加密的缺点是加密和解密花费时间长、速度慢,只适合对少许数据进行加密。session

被公钥加密过的密文只能被私钥解密。 加密过程:明文 + 加密算法 + 公钥 => 密文 解密过程:密文 + 解密算法 + 私钥 => 明文ide

被私钥加密过的密文只能被公钥解密。 加密过程:明文 + 加密算法 + 私钥 => 密文 解密过程:密文 + 解密算法 + 公钥 => 明文函数

3、HTTPS加密

非对称加密比对称加密更加安全,那么HTTPS中使用的是非对称加密吗?不是的。https使用的是混合加密的方式。那什么是混合加密呢?

如上图所示,HTTPS协议在链接时使用的是非对称加密。在数据传输过程当中,使用的是对称加密。

由于非对称加密速度慢,不合适在数据传输过程加密。因此在传输过程当中使用对称加密。而为了网络请求的安全性,因此在链接过程当中使用了非对称加密。

4、HTTPS通信过程

那么HTTPS的通信过程是怎样的呢?

  • 客户端使用HTTPS的URL访问服务器,与Web服务器创建SSL链接。
  • Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
  • 客户端浏览器与Web服务器开始协商SSL/TLS链接的安全等级,也就是信息加密的等级。
  • 客户端浏览器根据双方赞成的安全等级,创建会话密钥,而后利用网站的公钥将会话密钥加密,并传送给网站。
  • Web服务器利用本身的私钥解密出会话密钥。
  • Web服务器利用会话密钥加密与客户端之间的通讯。
  • 在当前未断开以前,客户端向服务端发送的消息都使用会话密钥加密,服务端再使用会话密钥解密。

5、网络挑战

举个栗子🌰:

let urlBD = "https://47.105.168.156:20199/"

Alamofire.request(urlBD, method: .get, parameters: ["users": "bar"])
    .response { (response) in
        print(response)
}
复制代码

在上面👆的栗子中,咱们向一个https地址发起了网络请求。运行以后会发现报了一些错误。

TIC SSL Trust Error [1:0x600000a592c0]: 3:0
...
Task <C47E510C-D9F5-4C62-9EB0-D58FFF71A638>.<1> finished with error - code: -1202
Task <C47E510C-D9F5-4C62-9EB0-D58FFF71A638>.<1> load failed with error Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “47.105.168.156” which could put your confidential information at risk."
复制代码

根据错误信息,大概是说服务器的证书失效。那么这个错误应该如何修复呢?想要修复这个错误,咱们应该知道,这个错误是什么时候打印的。

咱们从错误信息中看到有 finished with error,那么咱们在 didCompleteWithError 函数中断点调试一下。

断点后发现,在进入 didCompleteWithError 回调函数以前,已经打印了错误信息。因此,咱们的猜想不成立。

咱们知道,全部的网络请求都会走 SessionDelegate 的回调。既然不在 didCompleteWithError 回调函数,那会不会在其余回调函数呢?而后咱们就会找到这样一个回调函数:

从注释文档来看,这是和证书相关的回调。咱们断点调试一下,发现确实会来到这里。而且会调用 delegate.urlSession 回调函数。

就是这个回调函数,并且会由于红框中的判断没有成功而直接跳出执行。因此,这里就是错误的关键,这其实就是常说的 网络挑战

session.serverTrustPolicyManagerURLSession 的一个关联属性。那它是什么时候设置的呢? 还记得在【Alamofire之SessionManager】分析 SessionManager 初始化的时候见过这个属性,可是当时没有分析。

因此咱们应该在 SessionManager 的初始化时应该多一个参数 serverTrustPolicyManager

咱们自定义一个 SessionManager

func boManager() -> SessionManager {
    
    // 第一个参数是要信任的主机host
    let policies: [String: ServerTrustPolicy] = [
        "47.105.168.156": .pinCertificates(certificates: ServerTrustPolicy.certificates(), validateCertificateChain: true, validateHost: true)
    ]
    
    // 其他参数使用默认值
    let sessionManager = SessionManager(serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies))
    
    return sessionManager
}
复制代码

使用 ServerTrustPolicyManager 初始化 SessionManager

ServerTrustPolicyManager 须要一个字典参数 policies。 字典的key是你认证的主机地址。value是一个枚举 ServerTrustPolicy

枚举 ServerTrustPolicy 有不少个case,小伙伴能够根据文档选择本身的方式。这里使用 pinCertificates 固定证书认证举例。

须要服务器给你一个证书,放入工程中。而后再使用自定义的 SessionManager 请求网络。

let urlBD = "https://47.105.168.156:20199/"

// 使用自定义SessionManager网络请求
self.sessionManager = boManager()
self.sessionManager?.request(urlBD)
    .response { (response) in
        print(response)
}
复制代码

从新运行,就会发现不会报以前的错误了。

若是小伙伴只是测试,或者本身写个demo,还可使用 .disableEvaluation 不验证证书。

// 不验证证书
let policies: [String: ServerTrustPolicy] = [
    "47.105.168.156": .disableEvaluation
]
复制代码

可是这样会很危险,小伙伴们慎用。

看到这里,不少小伙伴可能会有疑问了。由于平时咱们开发中没有这样设置过,都是直接网络请求,也没有报错。这是由于,上面适用的状况是自签证书。而咱们平时更多使用的是CA证书。

那么CA证书又是如何工做的呢?请看下图:

以上就是本篇Alamofire安全认证的所有内容。如有不足之处,请评论指正。

相关文章
相关标签/搜索