簡體   English   中英

如何在流打開后將NSStream(NSInputStream / NSOutputStream)轉換為SSL?

[英]How to convert NSStream (NSInputStream / NSOutputStream) to SSL after stream opened?

我從這段代碼中獲得了NSInputStream和NSOutputStream

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

    CFStreamCreatePairWithSocket(kCFAllocatorDefault, sslSocket!, &readStream, &writeStream)
    if readStream != nil && writeStream != nil {
        CFReadStreamSetProperty(readStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)
        CFWriteStreamSetProperty(writeStream!.takeUnretainedValue(), kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanTrue)

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

        // Create strong delegate reference to stop ARC deallocating the object
        inputDelegate = self
        outputDelegate = self

        // Now that we have a strong reference, assign the object to the stream delegates
        inputStream!.delegate = inputDelegate
        outputStream!.delegate = outputDelegate


        // Schedule our run loops. This is needed so that we can recieve NSStreamEvents
        inputStream!.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
        outputStream!.scheduleInRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)

        inputStream!.open()
        outputStream!.open()
    }

問題 :如何在打開后將這些流轉換為SSL?

試過跟隨,但我得到了NSOSStatusErrorDomain

該操作無法完成。 (OSStatus錯誤-9801)

if (sslEnable) {
    let sslSettings = [
        NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse,
        NSString(format: kCFStreamSSLPeerName): kCFNull,
        NSString(format: kCFStreamSSLIsServer): kCFBooleanTrue,
    ]
    CFReadStreamSetProperty(inputStream, kCFStreamPropertySSLSettings, sslSettings)
    CFWriteStreamSetProperty(outputStream, kCFStreamPropertySSLSettings, sslSettings)

}

設置套接字流

如你所知, NSStream 支持連接到iOS上的本地遠程主機; 使用CFStreamCreatePairWithSocketToHost創建CFStream實例,然后橋接到NSStream 代碼是正確的。

此外,打開后不會轉換ssl ; 您首先設置其屬性並配置連接,然后將其打開。

對於SSL安全性,NSStream定義了各種安全級別屬性[...]

您必須打開流之前設置該屬性。 一旦打開,它將通過握手協議找出連接另一端正在使用的SSL安全級別。

保護和配置連接

在打開流對象之前,您可能希望為與遠程主機的連接設置安全性和其他功能( 流編程指南 )。

if let inputStream = inputStream, let outputStream = outputStream {
    inputStream.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)
    outputStream.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode)

    if (sslEnable) {
        inputStream.setProperty(StreamSocketSecurityLevel.tlSv1,
                               forKey: Stream.PropertyKey.socketSecurityLevelKey)
        outputStream.setProperty(StreamSocketSecurityLevel.tlSv1,
                                 forKey: Stream.PropertyKey.socketSecurityLevelKey)

        let sslSettings = [
            NSString(format: kCFStreamSSLValidatesCertificateChain): kCFBooleanFalse,
            NSString(format: kCFStreamSSLPeerName): kCFNull,
            NSString(format: kCFStreamSSLIsServer): kCFBooleanTrue,
            ] as [NSString : Any]

        inputStream.setProperty(sslSettings,
                                forKey: Stream.PropertyKey(rawValue:
                                    kCFStreamPropertySSLSettings as String))
        outputStream.setProperty(sslSettings,
                                 forKey: Stream.PropertyKey(rawValue:
                                    kCFStreamPropertySSLSettings as String))

    }
    inputStream.open()
    outputStream.open()
}

這是Security框架中SecureTransport.herrSSLNegotiation的錯誤

-9801 The cipher suite negotiation failed.

也許您嘗試連接的服務器具有非常舊的SSL實現,或者您的服務器密碼套件配置與手機的配置不匹配。

資源

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM