使用HTTPDNS的IOS SDK时出现“Error Domain=NSURLErrorDomain Code=-1202”报错

问题描述

使用HTTPDNS的IOS SDK时,出现类似如下报错信息。

Error Domain=NSURLErrorDomain Code=-1202 "此服务器的证书无效。您可能正在连接到一个伪装成“XX.XX.XX.XX” (IP地址 )的服务器,这会威胁到您的机密信息的安全,或者 NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9843)"

问题原因

安全证书是自建证书,没有得到权威认证。

解决方案

参见HTTPS(含SNI)业务场景“IP直连”方案说明,对证书校验步骤的内容进行修改,具体内容参考如下。

Objective-C
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
                  forDomain:(NSString *)domain {
    serverTrust = AFChangeHostForTrust(serverTrust,domain);
    /*
     * 创建证书校验策略
     */
    NSMutableArray *policies = [NSMutableArray array];
    if (domain) {
        [policies addObject:(__bridge_transfer id) SecPolicyCreateSSL(true, (__bridge CFStringRef) domain)];
    } else {
        [policies addObject:(__bridge_transfer id) SecPolicyCreateBasicX509()];
    }
    /*
     * 绑定校验策略到服务端的证书上
     */
    SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef) policies);
    /*
     * 评估当前serverTrust是否可信任,
     * 官方建议在result = kSecTrustResultUnspecified 或 kSecTrustResultProceed
   * 的情况下serverTrust可以被验证通过,https://developer.apple.com/library/ios/technotes/tn2232/_index.html
     * 关于SecTrustResultType的详细信息请参考SecTrust.h
     */
    SecTrustResultType result;
    SecTrustEvaluate(serverTrust, &result);
    if (result == kSecTrustResultRecoverableTrustFailure) {
        CFDataRef errDataRef = SecTrustCopyExceptions(serverTrust);
        SecTrustSetExceptions(serverTrust, errDataRef);
        SecTrustEvaluate(serverTrust, &result);
    }
    return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
}

其中,添加了以下内容。

Objective-C
if (result == kSecTrustResultRecoverableTrustFailure)
    {
        CFDataRef errDataRef = SecTrustCopyExceptions(serverTrust);
        SecTrustSetExceptions(serverTrust, errDataRef);
        SecTrustEvaluate(serverTrust, &trustResult);
    }

更多信息

关于本方案针对SDK添加的内容,其原因可以参见以下官方文档:

适用于

  • HTTPDNS