iOS自建授信证书

2019-10-10  本文已影响0人  HF_K

问题

情况1:公司业务需要私有化部署,对方服务器证书不受信导致网络无法请求成功,需要进行授信处理,报错结果如下:

An SSL error has occurred and a secure connection to the server cannot be made.
发生SSL错误和与服务器的安全连接无法进行。

情况2:因为公司域名出现问题,导致部分网址打不开,查看相关错误显示是因为服务器证书不受信,报错结果如下:

The certificate for this server is invalid. You might be connecting to a server that is pretending to be “xxx.xxx.com” which could put your confidential information at risk.
这个服务器的证书是无效的。你可能会连接到一个服务器,它是伪装“xxx.xxx.com”,可以把您的机密信息处于危险之中。

客户端信任证书的过程:

  1. 当客户端要访问服务器的时候,服务器向客户端发送受保护的信任证书

  2. 客户端判断是否对客户端发送的证书进行信任

  3. 如果信任.则客户端会安装公钥在客户端,而服务器就拥有受保护证书的密钥,每一次向服务器请求数据的时候,服务器会先将要发送的数据进行密钥加密,客户端对所传数据通过公钥解密

解决办法

  1. 让服务器更换服务器上的证书。(这种方案是最为合理的)
  2. 需要我们自己来创建一个证书让它受信,步骤如下:
    1. Info.plist文件中设置中Allow Arbitrary Loads in Web Content设置为YES,如果已经设置了NSAllowsArbitraryLoadsYES,可以不用设置。

       <key>NSAppTransportSecurity</key>
       <dict>
           <key>NSAllowsArbitraryLoads</key>
           <true/>
           <key>NSAllowsArbitraryLoadsInWebContent</key>
           <true/>
       </dict>
      
不用设置理由 设置图片
2. 在WKNavigationDelegate代理方法中实现自创证书并让其受信任

Swift

func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    // 判断是否是信任服务器证书
    if challenge.protectionSpace.authenticationMethod
        == NSURLAuthenticationMethodServerTrust {
        // 告诉服务器,客户端信任证书
        // 创建凭据对象
        let card = URLCredential.init(trust: challenge.protectionSpace.serverTrust!)
        // 告诉服务器信任证书
        completionHandler(URLSession.AuthChallengeDisposition.useCredential, card)
    }
}

OC

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
    
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        
        NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
        
        completionHandler(NSURLSessionAuthChallengeUseCredential,card);
    }
}

附:
如果是网络请求需要在NSURLSessionDataDelegate代理方法中实现自创证书并让其受信任

//MARK: NSURLSessionDataDelegate
//只要请求的地址是HTTPS的, 就会调用这个代理方法
//challenge:质询
//NSURLAuthenticationMethodServerTrust:服务器信任
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
    NSLog(@"%@",challenge.protectionSpace);
    if (![challenge.protectionSpace.authenticationMethod isEqualToString:@"NSURLAuthenticationMethodServerTrust"]) return;
    /*
     NSURLSessionAuthChallengeUseCredential 使用证书
     NSURLSessionAuthChallengePerformDefaultHandling  忽略证书 默认的做法
     NSURLSessionAuthChallengeCancelAuthenticationChallenge 取消请求,忽略证书
     NSURLSessionAuthChallengeRejectProtectionSpace 拒绝,忽略证书
     */
    NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
    
    completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
}

参考资料:
关于 iOS 10 中 ATS 的问题

上一篇 下一篇

猜你喜欢

热点阅读