【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析 (2)

PKI (Public Key Infrastructure),公开密钥基础设施。它是一个标准,在这个标准之下发展出的为了实现安全基础服务目的的技术统称为PKI。 权威的第三方机构CA(认证中心)是PKI的核心, CA负责核实公钥的拥有者的信息,并颁发认证"证书",同时能够为使用者提供证书验证服务。 x.509是PKI中最重要的标准,它定义了公钥证书的基本结构。

证书申请过程

证书申请者向颁发证书的可信第三方CA提交申请证书相关信息,包括:申请者域名、申请者生成的公钥(私钥自己保存)及证书请求文件.cer等

CA通过线上、线下等多种手段验证证书申请者提供的信息合法和真实性。

当证书申请者提供的信息审核通过后,CA向证书申请者颁发证书,证书内容包括明文信息和签名信息。其中明文信息包括证书颁发机构、证书有效期、域名、申请者相关信息及申请者公钥等,签名信息是使用CA私钥进行加密的明文信息。当证书申请者获取到证书后,可以通过安装的CA证书中的公钥对签名信息进行解密并与明文信息进行对比来验证签名的完整性。

证书验证过程

验证证书本身的合法性(验证签名完整性,验证证书有效期等)

验证证书颁发者的合法性(查找颁发者的证书并检查其合法性,这个过程是递归的)

证书验证的递归过程最终会成功终止,而成功终止的条件是:证书验证过程中遇到了锚点证书,锚点证书通常指:嵌入到操作系统中的根证书(权威证书颁发机构颁发的自签名证书)。

证书验证失败的原因

无法找到证书的颁发者

证书过期

验证过程中遇到了自签名证书,但该证书不是锚点证书。

无法找到锚点证书(即在证书链的顶端没有找到合法的根证书)

访问的server的dns地址和证书中的地址不同

三、iOS实现支持HTTPS

在OC中当使用NSURLConnection或NSURLSession建立URL并向服务器发送https请求获取资源时,服务器会使用HTTP状态码401进行响应(即访问拒绝)。此时NSURLConnection或NSURLSession会接收到服务器需要授权的响应,当客户端授权通过后,才能继续从服务器获取数据。如下图所示:

【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析

非自签名证书验证实现

在接收到服务器返回的状态码为401的响应后,对于NSURLSession而言,需要代理对象实现URLSession:task:didReceiveChallenge:completionHandler:方法。对于NSURLConnection而言,需要代理对象实现connection:willSendRequestForAuthenticationChallenge: 方法(OS X v10.7和iOS5及以上),对于早期的版本代理对象需要实现代理对象要实现connection:canAuthenticateAgainstProtectionSpace:和connection:didReceiveAuthenticationChallenge:方法。代码如下(参考文档):

【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析

当客户端发送https请求后,服务器会返回需要授权的相关信息,然后connection:willSendRequestForAuthenticationChallenge:方法被调用。客户端根据返回的challenge信息,首先获取需要验证的信任对象trust,然后调用SecTrustEvaluate方法是用系统默认的验证方式对信任对象进行验证,当验证通过时,使用该信任对象trust生成证书凭证,然后self.connection使用该凭证继续连接。如下详解:

NSURLAuthenticationChallenge包含如下信息:

error :最后一次授权失败的错误信息

failureResponse :最后一次授权失败的错误信息

previousFailureCount :授权失败的次数

proposedCredential :建议使用的证书

protectionSpace :NSURLProtectionSpace对象,代表了服务器上的一块需要授权信息的区域。包括了服务器地址、端口等信息。在此指的是challenge.protectionSpace。其中Auth-scheme指protectionSpace所支持的验证方法,NSURLAuthenticationMethodServerTrust指对protectionSpace执行证书验证。

【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析

sender:发送者,在此指的是self.connection

【腾讯Bugly干货分享】iOS 中 HTTPS 证书验证浅析

SecTrustRef

表示需要验证的信任对象(Trust Object),在此指的是challenge.protectionSpace.serverTrust。包含待验证的证书和支持的验证方法等。

SecTrustResultType

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzspjy.html