我有来自此代码的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)
}
答案 0 :(得分:2)
如您所知,NSStream
不支持在iOS上连接到远程主机;您使用CFStream
创建CFStreamCreatePairWithSocketToHost
的实例,然后桥接到NSStream
。代码是正确的。
此外,在打开后,您不会将转换为ssl
;您首先设置其属性并配置连接,然后将其打开。
对于SSL安全性,NSStream定义了各种安全级别属性[...]
您必须在之前设置属性才能打开流。一旦打开,它将通过握手协议找出连接另一端正在使用的SSL安全级别。
在打开流对象之前,您可能希望为与远程主机(Stream Programming Guide)的连接设置安全性和其他功能。
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()
}
答案 1 :(得分:1)
这是errSSLNegotiation
框架中SecureTransport.h
中Security
的错误
-9801 The cipher suite negotiation failed.
您尝试连接的服务器可能具有非常旧的SSL实施,或者您的服务器密码套件配置与手机的配置不匹配。