前言
HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。但是传输的过程是通过明文来传输。带来了三大风险
- 窃听风险(eavesdropping):第三方可以获知通信内容。
- 篡改风险(tampering):第三方可以修改通信内容。
- 冒充风险(pretending):第三方可以冒充他人身份参与通信。
在安全问题日益突出的情况下,互联网标准化组织 ISOC 基于 HTTP 协议通信推出了 SSL/TLS 协议 也就是 HTTPS , HTTPS 协议具有
- 所有信息都是加密传播,第三方无法窃听。
- 具有校验机制,一旦被篡改,通信双方会立刻发现。
- 配备身份证书,防止身份被冒充。
数字证书
数字证书:该证书包含了公钥等信息,一般是由服务器发给客户端,接收方通过验证这个证书是不是由信赖的CA签发,或者与本地的证书相对比,来判断证书是否可信;假如需要双向验证,则服务器和客户端都需要发送数字证书给对方验证;
发展历史
1994年,NetScape公司设计了SSL协议(Secure Sockets Layer)的1.0版,但是未发布。
1995年,NetScape公司发布SSL 2.0版,很快发现有严重漏洞。
1996年,SSL 3.0版问世,得到大规模应用。
1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。
2006年和2008年,TLS进行了两次升级,分别为TLS 1.1版和TLS 1.2版。最新的变动是2011年TLS 1.2的修订版。
目前,应用最广泛的是TLS 1.0,接下来是SSL 3.0。但是,主流浏览器都已经实现了TLS 1.2的支持。
TLS 1.0通常被标示为SSL 3.1,TLS 1.1为SSL 3.2,TLS 1.2为SSL 3.3。
通信原理
握手阶段分为 4 个步骤
1、客户端发起请求 (ClientHello)
客户端向服务器提供
- 支持的协议版本,比如TLS 1.0版。
- 一个客户端生成的随机数,稍后用于生成"对话密钥"。
- 支持的加密方法,比如RSA公钥加密。
- 支持的压缩方法。
2、服务器回应 (SeverHello)
服务器收到 ClientHello, 并作出回应。此时服务器向客户端发送
- 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
- 一个服务器生成的随机数,稍后用于生成"对话密钥"。
- 确认使用的加密方法,比如RSA公钥加密。
- 服务器证书。
3、客户端回应
客户端收到服务器回应以后,首先验证服务器证书。如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,由其选择是否还要继续通信。
验证通过之后客户端会向服务端发送
- 一个随机数(pre-master key)。该随机数用服务器公钥加密,防止被窃听(服务器可以通过私钥来解密出公钥加密的内容)。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
4、服务器最后回应
服务器收到客户端的第三个随机数pre-master key之后,根据之前的 2 个随机数(ClientHello 和 SeverHello 阶段)计算生成本次会话所用的"会话密钥"。然后,向客户端最后发送下面信息。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
传输过程
在结束上面4次握手通信之后,客户端和服务端就可以进入安全的传输过程。使用普通的HTTP协议,只不过用"会话密钥"加密解密内容。
iOS 中关于 HTTPS 的验证
iOS 关于 HTTPS 验证的 API 在 Security.Framework 框架中, 在使用 NSURLSession 时
在正规的 CA 机构申请证书的情况下:
(1) 在回调
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;
中我们会收到系统的鉴定请求。获取需要验证的信任对象(Trust Object)challenge.protectionSpace.serverTrust
(2) 使用系统默认验证方式验证Trust Object。SecTrustEvaluate
方法会根据Trust Object的验证策略,一级一级往上,验证证书链上每一级数字签名的有效性,从而评估证书的有效性。
(3) 第二步验证通过,就可以直接验证通过,进入到下一步:使用Trust Object生成一份凭证([NSURLCredential credentialForTrust:serverTrust]),调用 completionHandler(disposition, credential)
来完成鉴劝过程。
自生成证书的情况下:
需要在第二步之前,调用SecTrustSetAnchorCertificates
来注册自己的证书到系统信任列表中,在进行上面的第二部过程即可完成校验。
网友评论