调用streamingContentKeyRequestData遇NSOSStatusErrorDomain -12158错误
FairPlay Streaming Error -12158: 证书链验证失败排查方案
这个错误码 -12158 对应的是 errSSLXCertChainInvalid,本质是证书链验证失败,大概率和你的FairPlay证书配置或使用方式有关,和Data转换方式关系不大。我来帮你拆解几个核心排查方向:
1. 先确认FairPlay证书的有效性
- 检查你的
fairplay.der是否是苹果官方颁发的有效FairPlay Streaming生产证书,不是临时测试证书或格式损坏的文件。 - 可以用OpenSSL命令验证证书格式:
如果命令报错,说明证书本身格式存在问题,需要重新导出正确的DER格式证书。openssl x509 -inform der -in fairplay.der -text -noout
2. 修复证书加载的容错逻辑
你当前用try? Data(contentsOf: certUrl)会静默忽略加载错误,建议改成显式判断,避免证书加载失败却没被发现:
guard let certPath = Bundle.main.path(forResource: "fairplay", ofType: "der"), let certUrl = URL(fileURLWithPath: certPath), let applicationCertificate = try? Data(contentsOf: certUrl) else { print("Failed to load FairPlay certificate: File missing or corrupted") resourceLoadingRequest.finishLoading(with: NSError(domain: "FairPlayError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Certificate load failed"])) return }
3. 验证Asset ID的正确性
- 确保
assetIDString是你打包HLS流时使用的原始Asset ID,必须和你向苹果申请证书时绑定的Asset ID规则完全匹配。很多时候是这里不匹配导致证书链验证失败。 - 打印
assetIDString和assetIDData,确认和服务器端配置的Asset ID完全一致(注意大小写、特殊字符是否一致)。
4. 检查HLS流的密钥标签格式
确认你HLS流的EXT-X-KEY标签格式符合FairPlay要求,例如:
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://your-asset-id-here",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
只有URI是skd://开头的格式,contentKeyIdentifierURL.host才能正确提取到Asset ID。
5. 其他环境配置检查
- 切换到真实设备测试:部分FairPlay功能在模拟器上存在限制,真实设备的测试结果更准确。
- 确认App已开启FairPlay权限:在Xcode的
Signing & Capabilities中添加FairPlay Streamingentitlement。
优化后的完整代码示例
guard let certPath = Bundle.main.path(forResource: "fairplay", ofType: "der"), let certUrl = URL(fileURLWithPath: certPath), let applicationCertificate = try? Data(contentsOf: certUrl) else { print("Failed to load FairPlay certificate") resourceLoadingRequest.finishLoading(with: NSError(domain: "FairPlayError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Certificate load failed"])) return } guard let contentKeyIdentifierURL = resourceLoadingRequest.request.url, let assetIDString = contentKeyIdentifierURL.host, let assetIDData = assetIDString.data(using: .utf8) else { print("Failed to extract valid Asset ID from request") resourceLoadingRequest.finishLoading(with: NSError(domain: "FairPlayError", code: -2, userInfo: [NSLocalizedDescriptionKey: "Invalid Asset ID"])) return } do { let spcData = try resourceLoadingRequest.streamingContentKeyRequestData(forApp: applicationCertificate, contentIdentifier: assetIDData, options: nil) // 继续向密钥服务器发送SPC请求获取CKC } catch { print("Error generating SPC: \(error.localizedDescription)") resourceLoadingRequest.finishLoading(with: error) }
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

