如何使用自签名证书为 TLS 创建 iOS NWConnection?
How to create iOS NWConnection for TLS with self signed cert?
我正尝试将 Apple 的新 NWConnection class 用于我的 MQTT 客户端。为了进行测试,我需要能够创建到本地测试代理的 TLS 连接,该代理具有自签名证书。
到目前为止,我只是使用以下方式设置连接:
self.connection = NWConnection(host: NWEndpoint.Host("172.16.202.172"), port: NWEndpoint.Port(integerLiteral: 8899), using: .tls)
但是当我连接时,我的控制台上出现以下问题:
2019-01-30 17:05:51.010580-0800 myAp[2591:608137] [] nw_socket_handle_socket_event [C4.1:1] Socket SO_ERROR [54: Connection reset by peer]
2019-01-30 17:05:57.939157-0800 myApp[2591:608135] [BoringSSL] boringssl_context_alert_callback_handler(3724) [C5:1][0x103e087d0] Alert level: fatal, description: certificate unknown
2019-01-30 17:05:57.939382-0800 myApp[2591:608135] [BoringSSL] boringssl_context_error_print(3676) boringssl ctx 0x282226af0: 4360838776:error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED:/BuildRoot/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-109.230.1/ssl/handshake.cc:360:
2019-01-30 17:05:57.939510-0800 myApp[2591:608135] [BoringSSL] boringssl_context_get_error_code(3560) [C5:1][0x103e087d0] SSL_AD_CERTIFICATE_UNKNOWN
过去,当我使用 URLSession.shared.dataTask
从 nginx https 服务器下载文件时,我将以下内容添加到我的 info.plist
<dict>
<key>App Transport Security Settings</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>172.16.202.172</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionsAllowsInsecureHTTPSLoads</key>
<true/>
</dict>
</dict>
</dict>
</dict>
但在这种情况下,这似乎并没有奏效。当我单击 Apple 的文档链接以获取诸如 NWParameter
之类的内容以代替股票 .tls
时,以为我可以调整 xls 设置,但 Apple 文档中没有任何信息。
那么使用自签名证书为 TLS 通信创建 NWConnection
的正确方法是什么?
我不确定这是否是 complete/best 答案,但我在 Apple Developer 论坛上找到了这种方法:
func createTLSParameters(allowInsecure: Bool, queue: DispatchQueue) -> NWParameters {
let options = NWProtocolTLS.Options()
sec_protocol_options_set_verify_block(options.securityProtocolOptions, { (sec_protocol_metadata, sec_trust, sec_protocol_verify_complete) in
let trust = sec_trust_copy_ref(sec_trust).takeRetainedValue()
var error: CFError?
if SecTrustEvaluateWithError(trust, &error) {
sec_protocol_verify_complete(true)
} else {
if allowInsecure == true {
sec_protocol_verify_complete(true)
} else {
sec_protocol_verify_complete(false)
}
}
}, queue)
return NWParameters(tls: options)
}
self.workQueue = DispatchQueue(label: "mqtt")
self.connection = NWConnection(
host: NWEndpoint.Host("172.16.202.172"),
port: NWEndpoint.Port(integerLiteral: 8899),
using: createTLSParameters(allowInsecure: true, queue: self.workQueue))
使用此技术,我根本不需要 info.plist 更改。
上述论坛上有一些迹象表明,最好以某种方式将自签名证书放入您的 iOS 框中。
我正尝试将 Apple 的新 NWConnection class 用于我的 MQTT 客户端。为了进行测试,我需要能够创建到本地测试代理的 TLS 连接,该代理具有自签名证书。
到目前为止,我只是使用以下方式设置连接:
self.connection = NWConnection(host: NWEndpoint.Host("172.16.202.172"), port: NWEndpoint.Port(integerLiteral: 8899), using: .tls)
但是当我连接时,我的控制台上出现以下问题:
2019-01-30 17:05:51.010580-0800 myAp[2591:608137] [] nw_socket_handle_socket_event [C4.1:1] Socket SO_ERROR [54: Connection reset by peer]
2019-01-30 17:05:57.939157-0800 myApp[2591:608135] [BoringSSL] boringssl_context_alert_callback_handler(3724) [C5:1][0x103e087d0] Alert level: fatal, description: certificate unknown
2019-01-30 17:05:57.939382-0800 myApp[2591:608135] [BoringSSL] boringssl_context_error_print(3676) boringssl ctx 0x282226af0: 4360838776:error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED:/BuildRoot/Library/Caches/com.apple.xbs/Sources/boringssl/boringssl-109.230.1/ssl/handshake.cc:360:
2019-01-30 17:05:57.939510-0800 myApp[2591:608135] [BoringSSL] boringssl_context_get_error_code(3560) [C5:1][0x103e087d0] SSL_AD_CERTIFICATE_UNKNOWN
过去,当我使用 URLSession.shared.dataTask
从 nginx https 服务器下载文件时,我将以下内容添加到我的 info.plist
<dict>
<key>App Transport Security Settings</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>172.16.202.172</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSTemporaryExceptionsAllowsInsecureHTTPSLoads</key>
<true/>
</dict>
</dict>
</dict>
</dict>
但在这种情况下,这似乎并没有奏效。当我单击 Apple 的文档链接以获取诸如 NWParameter
之类的内容以代替股票 .tls
时,以为我可以调整 xls 设置,但 Apple 文档中没有任何信息。
那么使用自签名证书为 TLS 通信创建 NWConnection
的正确方法是什么?
我不确定这是否是 complete/best 答案,但我在 Apple Developer 论坛上找到了这种方法:
func createTLSParameters(allowInsecure: Bool, queue: DispatchQueue) -> NWParameters {
let options = NWProtocolTLS.Options()
sec_protocol_options_set_verify_block(options.securityProtocolOptions, { (sec_protocol_metadata, sec_trust, sec_protocol_verify_complete) in
let trust = sec_trust_copy_ref(sec_trust).takeRetainedValue()
var error: CFError?
if SecTrustEvaluateWithError(trust, &error) {
sec_protocol_verify_complete(true)
} else {
if allowInsecure == true {
sec_protocol_verify_complete(true)
} else {
sec_protocol_verify_complete(false)
}
}
}, queue)
return NWParameters(tls: options)
}
self.workQueue = DispatchQueue(label: "mqtt")
self.connection = NWConnection(
host: NWEndpoint.Host("172.16.202.172"),
port: NWEndpoint.Port(integerLiteral: 8899),
using: createTLSParameters(allowInsecure: true, queue: self.workQueue))
使用此技术,我根本不需要 info.plist 更改。
上述论坛上有一些迹象表明,最好以某种方式将自签名证书放入您的 iOS 框中。