一、HTTPS的概念
HTTPS就是将HTTP协议数据包放到SSL/TSL层加密后,在TCP/IP层组成IP数据报去传输,以此保证传输数据的安全;而对于接收端,在SSL/TSL将接收的数据包解密之后,将数据传给HTTP协议层,就是普通的HTTP数据。
SSL/TLS
SSL/TLS是一种介于传输层(比如TCP/IP)和应用层(比如HTTP)的协议。它通过握手协议(Handshake Protocol)
和传输协议(Record Protocol)
来解决传输安全的问题。
SSL/TLS运行过程
SSL/TLS有两个阶段:握手协议和传输协议。握手协议就是建立起这个链接的过程,这个过程采用非对称加密,这个过程完毕后会生成一个对话秘钥,从而用这个对话秘钥进行对称加密,实现传输协议过程。
中间主要通过四次握手进行交换信息:
- 1.客户端发出请求,主要向服务端传递以下信息:
支持的SSL/TLS协议版本;
支持的加密套件列表(cipher suite)
;
支持的压缩算法列表(compression methods)
,用于后续的压缩传输;
产生的一个随机数random_C(random number)
,客户端有存留,稍后用于生成对话密钥(session key)
; - 2.服务端收到请求,向客户端回应以下信息:
根据客户端支持的SSL/TLS协议版本,和自己的比较确定使用的SSL/TLS协议版本,如果没有合适的,对话关闭;
回应加密套件,压缩算法;
产生的一个随机数random_S(random number)
,服务端有存留,稍后用于生成对话密钥(session key)
;
服务端数字证书(证明自己的身份,传递公钥);
如果需要验证客户端,发出请求,要求客户端提供证书; - 3.客户端收到服务端回应后,首先验证服务端证书,如果证书没有问题再向服务端发送信息:
如果服务端有请求证书,发送自己的数字证书;
在产生一个随机数pre-master key(random number)
,并且用服务端数字证书中的公钥加密;
编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送; - 4.服务端最后的回应,如果有客户端证书首先验证证书,然后想客户端发送信息:
使用自己的私钥,对随机数pre-master ke
y解密,这时客户端和服务端各自有了三个随机数,然后用原来协商的加密方式生成本次通话使用的会话密钥(session key)
;
编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送;
这时通过会话秘钥将数据进行对称加密,然后进入传输协议过程。
二、HTTPS的实际应用
NSURLSession支持HTTPS
NSURLSession对证书的认证有两个代理方法,Server Hello阶段后会来到这两个代理方法中的其中一个,SSL/TLS第三个阶段主要就在这儿实现。
// 会话级别的回调
- (void)URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler
// 任务级别的回调
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler
两个代理方法的区别就是第二个回调多了一个task,
如果同时实现两个代理方法,则有回调优先级别更高的会话代理方法。
AFNetworking支持HTTPS
AFNetworking支持HTTPS相关的类为AFSecurityPolicy,其中AFNetworking提供了三种验证方式:
typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
AFSSLPinningModeNone,
AFSSLPinningModePublicKey,
AFSSLPinningModeCertificate,
};
//AFSSLPinningModeNon表示不做SSL pinning,只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书,是不会通过的。
//AFSSLPinningModeCertificate表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
//AFSSLPinningModePublicKey是用证书绑定方式验证,客户端要有服务端的证书拷贝,只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。