iOS端Flutter应用配置自签名证书实现文件下载问题求助
Flutter iOS 端自签名证书 SSL 连接问题解决思路
针对你遇到的iOS端无法通过自签名证书建立SSL连接的问题,可从以下几个方向排查解决:
1. 修正ATS配置的证书固定策略
你当前使用的NSPinnedCAIdentities适用于信任CA签发的证书场景,但自签名证书本身属于叶子证书(无上层CA),改用NSPinnedLeafIdentities更合适。同时建议添加子域名包含配置,调整后的Info.plist配置如下:
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <false/> <key>NSPinnedDomains</key> <dict> <key>subdomain.domain.com</key> <dict> <key>NSPinnedLeafIdentities</key> <array> <dict> <key>SPKI-SHA256-BASE64</key> <string>+V2Jp3+Q27t23D7amlWpiIFQfx0TivlE6MjvpR7iLC4=</string> </dict> </array> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> </dict>
2. 重新验证SPKI哈希的生成过程
确保你生成哈希时使用的是正确的自签名根证书文件,并简化命令避免冗余步骤,重新生成的命令如下:
openssl x509 -in iotccpem -noout -pubkey | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl base64
生成后对比原哈希值,若不一致说明之前的证书文件或命令步骤有误。
3. 针对Background Downloader库的原生层适配
由于该库可能未暴露badCertificateCallback,需在iOS原生代码中自定义URLSession的证书信任逻辑:
- 将
iotccpem.pem证书文件添加到iOS项目的Bundle中(勾选「Copy items if needed」); - 在
AppDelegate.swift或SceneDelegate.swift中实现URLSession的证书验证代理方法:
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { guard let serverTrust = challenge.protectionSpace.serverTrust else { completionHandler(.cancelAuthenticationChallenge, nil) return } // 加载本地证书 guard let certPath = Bundle.main.path(forResource: "iotccpem", ofType: "pem"), let certData = try? Data(contentsOf: URL(fileURLWithPath: certPath)), let cert = SecCertificateCreateWithData(nil, certData as CFData) else { completionHandler(.cancelAuthenticationChallenge, nil) return } // 将本地证书设为信任锚点 SecTrustSetAnchorCertificates(serverTrust, [cert] as CFArray) SecTrustSetAnchorCertificatesOnly(serverTrust, true) // 验证信任链 var trustResult: SecTrustResultType = .invalid SecTrustEvaluate(serverTrust, &trustResult) if trustResult == .unspecified || trustResult == .proceed { let credential = URLCredential(trust: serverTrust) completionHandler(.useCredential, credential) } else { completionHandler(.cancelAuthenticationChallenge, nil) } }
- 若库支持自定义URLSessionConfiguration,将上述代理逻辑绑定到对应的Session中。
4. 验证本地证书格式有效性
用以下命令检查证书文件是否为合法的PEM格式:
openssl x509 -in iotccpem -text -noout
若命令能输出证书的详细信息(如有效期、公钥等),说明证书格式无问题;若报错需重新导出正确的PEM格式证书。
内容的提问来源于stack exchange,提问作者chrjs
相关产品推荐
相关产品推荐

