如何修复 iOS 中的“TIC SSL 信任错误”?

How to fix ‘TIC SSL Trust Error’ in iOS?

当我尝试使用网络服务登录应用程序时。 我也像下面这样设置我的 plist-file

我收到以下错误。 我的控制台上显示此错误

TIC SSL Trust Error [5:0x1c017fbc0]: 3:0
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Task <E0C414FF-98C7-4E6B-876F-B9006465C8FD>.<1> HTTP load failed (error code: -1200 [3:-9802]

Apple 开发者文档指南。

ssl 更改 iOS 11 https://forums.developer.apple.com/thread/80197

证书查看器还有更具体的消息传递。在下面的屏幕截图中,您可以看到显示了针对特定信任错误的警告。在这种情况下,错误显示为“无法验证此证书(弱摘要算法)”,因为它是使用 SHA-1 签名的。

在某些情况下,连接到服务器并向其发出命令以进行测试很有用。对于典型的 Internet 协议(HTTP、SMTP、NNTP 等),您可以使用 telnet 工具执行此操作。但是,如果协议使用 TLS,这将不起作用。在这种情况下,您最好的选择是 openssl 工具的 s_client 子命令。清单 1 展示了如何使用该工具手动获取内容(记住 HTTPS 使用端口 443)。

清单 1 使用 openssl s_client

$ openssl s_client -connect www.apple.com:443
CONNECTED(00000003)
[...]
GET / HTTP/1.1
Host: www.apple.com

HTTP/1.1 200 OK
Server: Apache/2.2.3 (Oracle)
Content-Length: 9464
Content-Type: text/html; charset=UTF-8
ntCoent-Length: 9516
Cache-Control: max-age=47
Expires: Mon, 25 Jun 2012 16:18:24 GMT
Date: Mon, 25 Jun 2012 16:17:37 GMT
Connection: keep-alive

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US">
[...]
</html>
closed
$

s_client 子命令支持许多有用的调试选项。例如:

您可以提供 -cert 参数让它响应客户端证书请求。 您可以指定 -showcerts 选项以获取服务器提供的证书的完整列表。 -debug 和 -msg 选项启用低级调试功能。 有关这些选项等的更多信息,请参阅手册页。

以下代码适用于我。我为 NSURLSessionDelegate (didReceiveChallenge)

实现了委托方法
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:Nil];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
                    //Handle the response
   }];
[task resume];

//NSURLSessionDelegate方法

  - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler{

      if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
        if([challenge.protectionSpace.host isEqualToString:@"yourdomain.com"]){
          NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
      completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
    }
  }
}

您可以在 Appdelegate.m

中输入

代码如下:

@implementation NSURLRequest(DataController)
   + (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host{
   return YES;
}  

IKKA - 在Swift 4.2 版本

中的回答
extension CustomViewController: URLSessionDelegate {
    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate) {
            completionHandler(.rejectProtectionSpace, nil)
        }
        if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
            let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
            completionHandler(.useCredential, credential)
        }
    }
}

Swift 5.1

您的 class 必须遵守 URLSessionDelegate 并实现 "didReceive Challenge" 功能。

这些 Apple 开发者页面说明了这个问题,并提供了很多关于如何安全解决这个问题的见解:

Handling an Authentication Challenge

Performing Manual Server Trust Authentication

以下示例说明了如何为开发或 QA 环境解决此问题:

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    #if DEBUG
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
        if challenge.protectionSpace.host == "YourTrustedDevOrQaDomain" {
            // At this point you can prevent a domain that is pretending to be a trusted domain by challenging the user to present some credentials or a security mechanism for authentication. 
            if let serverTrust = challenge.protectionSpace.serverTrust {
                let credential = URLCredential(trust: serverTrust)
                completionHandler(URLSession.AuthChallengeDisposition.useCredential, credential)
            }
        }
    }
    #endif
}