https
AFNetworking是现今使用最广泛的基于Object-c的网络库,https现在也得到推广,越来越多的网站开始使用https来加强数据的安全性。本篇文章从https的设计理念出发,详细讲解https为什么要这么设计?最后过渡到解析AFNetworking如何设计和实现网络安全模块
https设计思路
http协议的数据是明文传输的,面临三大风险:
- 消息被窃听
- 消息被篡改
- 身份被冒充
https要保障信息传输的安全,需要解决这三个问题:
- 消息被窃取也无法知道具体的内容(加密)
- 消息内容无法被篡改(数字签名)
- 身份认证(数字证书)
要保障客户端A和服务器B知道消息的具体内容,很容易想到使用加密技术,对消息进行加密。因此我们需要了解一下加密相关知识,加密可以分为对称加密和非对称加密。生活中我们碰到的大部分锁和钥匙是分离的,而计算机中加密和生活中略有不同,”锁”和”钥匙”是在一起的,称为密钥,即能加密又能解密。
对称加密
对称加密算法的特点是算法公开、计算量小、加密速度快、加密效率高。对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中。不足之处是,交易双方都使用同样密钥,安全性得不到保证。常见的对称加密有 DES、AES 等。个人理解类似于生活中比较复杂的数字密码锁,用该密码锁”锁住”信息,拥有密钥即知道密码的人可以打开该密码锁,获取的具体内容,其他人则只能获取到密文消息。
非对称加密
非对称加密使用一对“私钥-公钥”,私钥和公钥即能加密又能解密,用私钥加密的内容只有对应公钥才能解开,反之亦然。非对称加密有以下特性:
- 对于一个公钥,有且只有一个对应的私钥。
- 公钥是公开的,并且不能通过公钥反推出私钥。
- 通过私钥加密的密文只能通过公钥能解密,通过公钥加密的密文也只能通过私钥能解密。
非对称加密不需要共享同一份秘钥,安全性要比对称加密高,但由于算法强度比对称加密复杂,加解密的速度比对称加解密的速度要慢。常见的非对称加密有 RSA、ESA、ECC 等。
基于加密算法的两种设计思路
基于非对称加密算法的特性,可以设计客户端和服务器端同时使用非对称加密则可以保障信息的安全
- 使用非对称加密
- 使用对称加密
两种方案都能解决信息加密的问题,但是因为非对称密码算法有两个缺点 :
- 加密速度慢, 比对称加密算法慢 10 ~ 100 倍 , 因此只可用其加密小数据 (如对称密钥),
- 加密后会导致得到的密文变长。
因此一般采用对称加密算法加密其文件, 然后用非对称算法加密对称算法所用到的对称密钥。针对http报文加密选用对称加密更合适。
使用该方案解决了消息的被窃取和被篡改两个问题,但是还存在两个问题:
- 如何保障用于对称加密的密钥的安全
- 如何验证通信双方身份,防止身份伪造
协商生成密钥的过程使用非对称加密就能保证密钥的安全,https也是使用该思路,大致分两个阶段:
- 使用非对称加密算法加密协商生成对称加密的过程
- 使用对称加密算法和协商的密钥加密传输的数据
上述过程有一个问题需要解决,客户端A如何获取服务器B的公钥以及证明该公钥就是服务器B的。可能方案:服务器B将公钥发送给客户端A或放到远端服务器,又会引入公钥传输的安全问题。在这里引入第三方机构认证解决循环依赖问题,使用数字证书来做身份验证。
摘要算法
摘要算法在互联网安全体系中也扮演了重要的角色。摘要算法有以下特性:
- 只要源文本不同,计算得到的结果,必然不同(或者说机会很少)。
- 无法从结果反推出源数据。
基于以上特性,我们一般使用摘要算法来校验原始内容是否被篡改。常见的摘要算法有 MD5、SHA 等。
数字签名
数字签名就是用摘要算法提取出源文件的摘要并用私钥进行加密后的内容,可以理解为生活中文件上的签名或盖章,标识该文件就出自签名者或盖章者并篡改无效。
数字证书
数字证书可以理解为”数字身份证”,主要包含证书主体相关信息、公钥以及这些信息的数字签名,由认证中心来验明身份。认证中心是一家能向用户签发数字证书以确认用户身份的管理机构
认证中心类似于DNS是一个分布式的树状结构:
验证证书的过程:
单向认证和双向认证过程
引入数字证书和数字签名后即可在上面非对称加密算法和对称加密算法基础上解决信息篡改和身份认证问题:
以上就是https双向认证的完整过程,完美的解决了http面临的三个问题。而https的使用更多的是使用单向验证,因为:
- 客户端身份的认证更多的是在应用层做而不是传输层并且对客户端认证没有那么严
- 每个客户端都需要唯一的证书,如果使用CA认证的会带来巨大的成本,使用自建证书还需要处理客户端获取证书的问题
https单向验证只是去掉了客户端证书的验证过程,具体如下:
QA:为什么要三个随机数?
三个随机数保证随机性,保证每次客户端和服务器生成的密钥不同,并且增加破解难度
charels抓https包原理
https的单向认证由于没有验证客户端身份,因此只需要破坏客户端验证服务器数字证书这一步即可完成中间人攻击,这就是charels抓取https包需要在客户端安装charles根证书的原因,这样客户端就会信任charels作为服务器。
AFSecurityPolicy
AFSecurityPolicy其实就是AFNetworking框架对客户端验证https证书是否可信任的封装和扩充。增加了客户端通过服务器证书验证的方式,即提前将服务器证书放到APP bundle或沙盒中,对比存储在客户端本地的证书和服务器证书来完成验证。
- 这种方式可以防止中间人攻击,因为不通过CA认证的流程,防止客户端系统信任了不合法的根证书
- 这种方式服务器可以使用自建证书(节约费用)
将验证证书分为三种模式:
1 | /** |
接下来声明了四个属性:
- SSLPinningMode:返回SSL Pinning的类型。默认的是AFSSLPinningModeNone。
- pinnedCertificates:保存着所有的可用做校验的证书的集合。只要在证书集合中任何一个校验通过,evaluateServerTrust:forDomain: 就会返回true,即通过校验。
- allowInvalidCertificates:允许使用无效或过期的证书,默认是NO不允许。
- validatesDomainName:是否验证证书中的域名domain,默认是YES。
声明了以下方法:
1 | /** |
核心方法:
1 | /** |
AFSecurityPolicy是AFHTTPSessionManager的一个属性,创建AFHTTPSessionManager时可以根据需求初始化和指定安全策略,当建立一个https的网络请求时,NSURLSessionDelegate会回调- URLSession:didReceive Challenge: completionHandler:方法,NSURLSessionTaskDelegate会回调-URLSession:task:didReceiveChallenge:completionHandle:r:,然后调用AFSecurityPolicy的evaluateServerTrust:进行服务器证书认证。
1 | /** |
AFSecurityPolicy核心方法实现解析:
1 | /** |
iOS 网络认证挑战
类结构图: