tencent cloud

移动解析 HTTPDNS

产品简介
产品介绍
应用场景
产品优势
产品限制
购买指南
计费说明
欠费说明
快速入门
开通移动解析 HTTPDNS
接入移动解析 HTTPDNS
操作指南
添加域名
解析量统计说明
解析监控
API 文档
配置信息说明
HTTP 请求方式查询
AES、DES 加密解密说明
API 接入实践教程
SDK 文档
SDK 快速接入
IOS SDK 文档
Android SDK 文档
访问管理及协作
访问管理概述
访问管理策略示例
常见问题
HTTPDNS 政策
隐私协议
数据处理和安全协议

HTTPS(非 SNI)场景

PDF
聚焦模式
字号
最后更新时间: 2025-09-05 17:52:26

原理

在进行证书校验时,将 IP 替换成原来的域名,再进行证书验证。

Demo 示例

NSURLSession 接口示例

#pragma mark - NSURLSessionDelegate
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)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);

return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler {
if (!challenge) {
return;
}

NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
NSURLCredential *credential = nil;

//获取原始域名信息
NSString *host = [[self.request allHTTPHeaderFields] objectForKey:@"host"];
if (!host) {
host = self.request.URL.host;
}
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if ([self evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:host]) {
disposition = NSURLSessionAuthChallengeUseCredential;
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}
} else {
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
}

// 对于其他的 challenges 直接使用默认的验证方案
completionHandler(disposition,credential);
}

NSURLConnection 接口示例

#pragma mark - NSURLConnectionDelegate
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)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);
return (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
}

- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
if (!challenge) {
return;
}

//URL 里面的 host 在使用 HTTPDNS 的情况下被设置成了 IP,此处从 HTTP Header 中获取真实域名
NSString *host = [[self.request allHTTPHeaderFields] objectForKey:@"host"];
if (!host) {
host = self.request.URL.host;
}

//判断 challenge 的身份验证方法是否是 NSURLAuthenticationMethodServerTrust(HTTPS 模式下会进行该身份验证流程),
//在没有配置身份验证方法的情况下进行默认的网络请求流程。
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if ([self evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:host]) {

//验证完以后,需要构造一个 NSURLCredential 发送给发起方
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
//验证失败,取消这次验证流程
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
} else {

//对于其他验证方法直接进行处理流程
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
}
}

Unity 的 WWW 接口示例

将 Unity 工程导出为 Xcode 工程后,打开 Classes/Unity/WWWConnection.mm 文件,修改下述代码:
//const char* WWWDelegateClassName = "UnityWWWConnectionSelfSignedCertDelegate";
const char* WWWDelegateClassName = "UnityWWWConnectionDelegate";
调整为:
const char* WWWDelegateClassName = "UnityWWWConnectionSelfSignedCertDelegate";
//const char* WWWDelegateClassName = "UnityWWWConnectionDelegate";

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈