Ich benutze Apples CFNetworking, um einen TLS-Stream zu erhalten. Ich habe ein paar Probleme mit der Portierung des Objective-C-Codes auf Swift.Unterschied zwischen Apple TLS mit Objective-C und Swift
Mit genau den gleichen Schritten funktioniert es, wenn Sie Objective-C verwenden, aber der Handshake schlägt bei Swift-Versuchen immer fehl.
Arbeits Obj-c
- (void)connect()
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
(__bridge CFStringRef)hostAddress,
port,
&readStream,
&writeStream);
self.inputStream = (__bridge_transfer NSInputStream *)readStream;
self.outputStream = (__bridge_transfer NSOutputStream *)writeStream;
[self.inputStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL
forKey:NSStreamSocketSecurityLevelKey];
[self.outputStream setProperty:NSStreamSocketSecurityLevelNegotiatedSSL
forKey:NSStreamSocketSecurityLevelKey];
[self.inputStream setDelegate:self];
[self.outputStream setDelegate:self];
[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[self.inputStream open];
[self.outputStream open];
}
Nichtarbeits Swift
func connect() {
var readStream: Unmanaged<CFReadStream>?
var writeStream: Unmanaged<CFWriteStream>?
let host = "some_host"
let hostAsCFString = host as NSString
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault,
hostAsCFString,
1337,
&readStream,
&writeStream)
inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()
inputStream!.delegate = self
outputStream!.delegate = self
inputStream!.setProperty(NSStreamSocketSecurityLevelNegotiatedSSL,
forKey: NSStreamSocketSecurityLevelKey)
outputStream!.setProperty(NSStreamSocketSecurityLevelNegotiatedSSL,
forKey: NSStreamSocketSecurityLevelKey)
inputStream!.scheduleInRunLoop(.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outputStream!.scheduleInRunLoop(.currentRunLoop(), forMode: NSDefaultRunLoopMode)
inputStream!.open()
outputStream!.open()
}
Beide versuchen, auf dem gleichen Server und denselben Port zu verbinden.
Bildschirm Grabs von wireshark:
Arbeiten Obj-C
Nichtarbeits Swift
ich ziemlich ratlos bin, was los ist, . Ich habe keine Ahnung, warum die Obj-C-Version einen Client Hello mit TLS v1.2 startet, aber Swift versucht mit TLS v1.0, dann gibt er einfach auf. Keine Ahnung, warum die Swift-Version so lange braucht, um den Client zu senden Hallo, wird vorher ein Keepalive-Paket gesendet? Jede Hilfe würde sehr geschätzt werden.
Dies ändert möglicherweise nichts, aber die Reihenfolge, in der Sie NStreamSocketSecurityLevelNegotiatedSSL festlegen, und der Delegat wird zwischen Ihren ObjC- und Swift-Versionen ausgetauscht. – zneak
Das ist egal. Der Handshake beginnt erst beim ersten Lese- oder Schreib-Aufruf an beiden Enden des Streams. – nathansizemore
Was ist mit dem Kontext, in dem diese 'connect()' Methode aufgerufen wird? Ist es auf dem Hauptthread? –