如何在 Swift 中将自生成的 ssl 证书与 NSStream(s) 一起使用

How to use a self generated ssl cert with NSStream(s) in Swift

我在接受套接字请求的云中有一个 python 服务器。我有一个 Swift (xCode) 客户端应用程序,它使用 NS(in/out)putstreams 与 python 服务器应用程序通信。

我在服务器上生成了自己的 SSL 证书和密钥文件。

通过在我的服务器端注释掉 SSL 包装代码,我可以让我的客户端和服务器正常通信。使用 SSL 我收到握手错误。

服务器和客户端都使用 TLSV1 作为安全级别协议。

在 mac 方面,我安装了我的服务器证书文件并允许在我的用户钥匙串中使用,但我认为该应用程序不会在那里寻找受信任的证书。

有没有一种方法可以直接在 xCode 应用程序中实用地指定证书文件供 NSStream 使用。或者在应用程序上安装证书的方法?

我在 python 中知道,当您使用 SSL 包装套接字时,您可以告诉它它是一个客户端并使用路径中的特定证书文件。是否有 MacOS Swift 等效项?

还是我做错了?

下面是我的"Light Socket"Swiftclass。超级简单,但在两端不使用 SSL 时工作。

class SSLSocketLite {

    // The input stream.
    private var inStream: NSInputStream?
    // The output stream.
    private var outStream: NSOutputStream?
    // The host to connect to.
    private var host: String
    // The port to connect on.
    private var port: Int

    init(inHost:String, inPort:Int) {
        host = inHost
        port = inPort
        NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inStream, outputStream: &outStream)
    }

    func Open() {
        inStream?.open()
        outStream?.open()

        inStream?.setProperty(NSStreamSocketSecurityLevelTLSv1, forKey: NSStreamSocketSecurityLevelKey)
        outStream?.setProperty(NSStreamSocketSecurityLevelTLSv1, forKey: NSStreamSocketSecurityLevelKey)
    }

    func Read() -> String! {
        var buffer = Array<UInt8>(count:1024, repeatedValue: 0)
        if inStream!.hasBytesAvailable {
            inStream!.read(&buffer, maxLength: 1024)
            let responseString = NSString(bytes: buffer, length: buffer.count, encoding: NSUTF8StringEncoding) as! String
            return responseString
        }
        return nil
    }

    func Write(msg:String) {
        let data:NSData = msg.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
        outStream!.write(UnsafePointer(data.bytes), maxLength: data.length)
    }

    func Close() {
        inStream?.close()
        outStream?.close()
    }
}

我从许多其他帖子中收集了所有这些内容,但找不到任何提及 Swift 调用实际使用证书文件与服务器通信的位置和时间。

如果我遗漏或误解了其中的关键要素,请告诉我!提前致谢!

我找到了答案。我在 open 方法中遗漏了这些行。

他们需要自动执行 SSL 握手。

inStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
outStream?.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)

我的其他问题仍然可以使用回答。

谢谢!