【问题标题】:TCP socket stream and SSL with SwiftTCP 套接字流和 SSL 与 Swift
【发布时间】:2020-02-27 03:11:09
【问题描述】:

我正在使用一个需要连接到套接字的简单客户端。此套接字需要 SSL...我正在尝试将客户端配置为支持 SSL,但出现此错误:

CFNetwork SSLHandshake failed (-9807)

这是我为配置套接字而编写的代码。你看到什么奇怪的/错误的吗? 另外...服务器正在本地主机上运行,​​而我目前正在模拟器上运行iOS应用程序...可能有问题吗?

class MySocket:NSObject {

    var inputStream: InputStream!
    var outputStream: OutputStream!

    func setupStream(){

        var readStream: Unmanaged<CFReadStream>?
        var writeStream: Unmanaged<CFWriteStream>?

        CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
                                           "127.0.0.1" as CFString,
                                           80,
                                           &readStream,
                                           &writeStream)

        inputStream = readStream!.takeRetainedValue()
        outputStream = writeStream!.takeRetainedValue()

        inputStream.delegate = self

        inputStream.schedule(in: .current, forMode: .common)
        outputStream.schedule(in: .current, forMode: .common)

    // SETTING SSL HERE
        inputStream.setProperty(kCFStreamSocketSecurityLevelNegotiatedSSL, forKey:  Stream.PropertyKey.socketSecurityLevelKey)
        outputStream.setProperty(kCFStreamSocketSecurityLevelNegotiatedSSL, forKey: Stream.PropertyKey.socketSecurityLevelKey)
    // END SSL SETUP

        inputStream.open()
        outputStream.open()

    }
}

【问题讨论】:

  • 您确定您的 localhost 服务器在端口 80 而不是 443 上通过 SSL 提供 TCP 服务吗?
  • @jms 是的,实际上端口是自定义端口....我在此示例中编写了端口 80,但我们使用的是自定义端口。
  • 您能否确认您的服务器已成功通过 ssl 将安全内容提供给其他客户端,这只是一个快速问题,因此我可以进行更多调查? (如果您担心127.0.0.1 则连接到另一个公共网络并使用来自ifconfig 的接口ip-address)
  • @jms 是的,我可以确认它可以在其他客户端上运行(我有一个非常简单的 python 脚本,可以连接到服务器并发送和接收数据)。
  • 我认为您将 SSL 属性设置在错误的位置。使用CFStream API 而不是低级 I/O 流。以下链接向您展示了如何将属性设置为 CFStream developer.apple.com/documentation/corefoundation/cfstream/…

标签: swift sockets


【解决方案1】:

我一直在查看库 SocketRocket 以检查您的代码。该库是在 Objective-C 中实现的,但您可以将其用作参考。

在该库中,在更新安全流选项的代码中,我观察到它只更新了 outputStream 的 kCFStreamSocketSecurityLevelNegotiatedSSL。

- (void)_updateSecureStreamOptions {
    if (_secure) {
        NSMutableDictionary *SSLOptions = [[NSMutableDictionary alloc] init];

        /*ONLY FOR OUTPUT STREAM*/
        [_outputStream setProperty:(__bridge id)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(__bridge id)kCFStreamPropertySocketSecurityLevel];

        // If we're using pinned certs, don't validate the certificate chain
        if ([_urlRequest SR_SSLPinnedCertificates].count) {
            [SSLOptions setValue:@NO forKey:(__bridge id)kCFStreamSSLValidatesCertificateChain];
        }

  #if DEBUG
        self.allowsUntrustedSSLCertificates = YES;
  #endif

        if (self.allowsUntrustedSSLCertificates) {
            [SSLOptions setValue:@NO forKey:(__bridge id)kCFStreamSSLValidatesCertificateChain];
            SRFastLog(@"Allowing connection to any root cert");
        }

        [_outputStream setProperty:SSLOptions
                            forKey:(__bridge id)kCFStreamPropertySSLSettings];
    }

    _inputStream.delegate = self;
    _outputStream.delegate = self;

    [self setupNetworkServiceType:_urlRequest.networkServiceType];
}

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2017-01-11
    • 1970-01-01
    • 2014-06-30
    • 1970-01-01
    • 2016-11-26
    相关资源
    最近更新 更多