Swift中didReceive challenge未调用引发SSL连接错误求助
针对SSL连接错误的解决方案
错误分析
你遇到的-9816错误属于SSL协议错误,结合Connection reset by peer提示,大概率是服务器的SSL配置与Apple平台的LibreSSL实现不兼容,或者服务器存在反爬机制拦截了非浏览器请求。
具体解决办法
1. 强制指定兼容的TLS版本
服务器可能仅支持特定TLS版本,尝试明确设置TLS版本范围:
let config = URLSessionConfiguration.default // 强制使用TLS 1.2(可根据服务器实际支持情况调整为1.1或1.3) config.tlsMinimumSupportedProtocolVersion = .TLSv12 config.tlsMaximumSupportedProtocolVersion = .TLSv12
2. 完全模拟Chrome的请求头
Chrome能正常访问,说明服务器认可Chrome的请求特征,替换User-Agent并补充完整请求头:
config.httpAdditionalHeaders = [ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1", "Cache-Control": "max-age=0" ]
3. 替换为同步版证书验证代理方法
你当前使用的异步版代理方法可能在部分场景下不触发,改用传统回调版:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { print("Challenging....") guard let serverTrust = challenge.protectionSpace.serverTrust else { completionHandler(.useCredential, nil) return } let credential = URLCredential(trust: serverTrust) completionHandler(.useCredential, credential) }
注意:移除原有的异步版方法,避免代理逻辑冲突
4. 自定义SSL密码套件
匹配Chrome使用的密码套件,强制LibreSSL使用兼容的套件组合:
// 可通过Chrome的`chrome://settings/security`页面查看支持的套件列表 config.tlsCipherSuites = [ "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305" ]
5. 排查网络环境干扰
- 关闭本地代理、VPN或防火墙,排除网络层拦截问题
- 切换至其他网络(如手机热点)测试,确认是否是本地网络限制导致的连接重置
6. 验证服务器证书链完整性
使用openssl命令检查服务器证书链是否完整:
openssl s_client -connect www.1tamilmv.eu:443
如果输出中出现unable to get local issuer certificate,说明证书链不完整,可手动下载根证书添加到系统钥匙串,或在代码中实现自定义证书链验证逻辑。
内容的提问来源于stack exchange,提问作者Vin
相关产品推荐
相关产品推荐

