在网络如此发达的今天,网络安全已经和每一个人息息相关了。今天咱们就一块儿来了解一下网络安全方面的相关知识。算法
咱们知道,在HTTP协议中,发送的内容是以明文的形式传递的。这就致使了如下几个缺陷:swift
为了解决上面👆几个缺陷,苹果官方推荐使用HTTPS传输协议。浏览器
HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议。重要的是比HTTP更安全。安全
在了解HTTPS协议以前,咱们须要先有一点密码学基础。bash
明文:是指未被加密过的原始数据
复制代码
密文:明文被某个加密方式(算法)加密后,就变成了密文。密文能够被解密获得明文
复制代码
密钥:是在明文转换为密文的算法中所使用的参数。
密钥分为对称密钥和非对称密钥。分别对应对称加密和非对称加密。
复制代码
对称加密:对称加密又叫作私钥加密,即信息的发送方和接收方使用同一个密钥去加密和解密数据。
复制代码
对称加密的特色是算法公开、加密和解密速度快,适合于对大数据量进行加密。服务器
对称加密加密过程:明文 + 加密算法 + 私钥 => 密文 对称加密解密过程:密文 + 解密算法 + 私钥 => 明文网络
非对称加密:非对称加密也叫作公钥加密。非对称加密使用一对密钥,即公钥和私钥,且两者成对出现。用公钥或私钥中的任何一个进行加密,用另外一个进行解密。
复制代码
非对称加密的缺点是加密和解密花费时间长、速度慢,只适合对少许数据进行加密。session
被公钥加密过的密文只能被私钥解密。 加密过程:明文 + 加密算法 + 公钥 => 密文 解密过程:密文 + 解密算法 + 私钥 => 明文ide
被私钥加密过的密文只能被公钥解密。 加密过程:明文 + 加密算法 + 私钥 => 密文 解密过程:密文 + 解密算法 + 公钥 => 明文函数
非对称加密比对称加密更加安全,那么HTTPS中使用的是非对称加密吗?不是的。https使用的是混合加密的方式。那什么是混合加密呢?
如上图所示,HTTPS协议在链接时使用的是非对称加密。在数据传输过程当中,使用的是对称加密。
由于非对称加密速度慢,不合适在数据传输过程加密。因此在传输过程当中使用对称加密。而为了网络请求的安全性,因此在链接过程当中使用了非对称加密。
那么HTTPS的通信过程是怎样的呢?
举个栗子🌰:
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.serverTrustPolicyManager
是 URLSession
的一个关联属性。那它是什么时候设置的呢? 还记得在【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安全认证的所有内容。如有不足之处,请评论指正。