我有一个简单的 TCP 服务器/客户端设置。这种连接实际上很好用。
现在我想为套接字连接实现 SSL / TLS 加密。我使用钥匙串访问创建了一个 PKCS12 证书。在我的服务器中,我在接受回调中有以下代码:
NSString *certificatePath = [[NSBundle mainBundle] pathForResource:@"TCPServerCertificate" ofType:@"p12"];
NSData *certificateData = [NSData dataWithContentsOfFile:certificatePath];
CFArrayRef keyRef;
OSStatus status = SecPKCS12Import((__bridge CFDataRef)certificateData, (__bridge CFDictionaryRef)@{(__bridge NSString *)kSecImportExportPassphrase: @"1234"}, &keyRef);
if (status != noErr) {
NSLog(@"PKCS12 import error %i", status);
return;
}
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(keyRef, 0);
SecIdentityRef identityRef = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
SecCertificateRef certificate;
status = SecIdentityCopyCertificate(identityRef, &certificate);
if (status != noErr) {
NSLog(@"sec identity copy failed: %i", status);
return;
}
NSArray *certificates = [NSArray arrayWithObjects:(__bridge id)identityRef, (__bridge id)certificate, nil];
NSDictionary *settings = @{(NSString *)kCFStreamPropertyShouldCloseNativeSocket: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLValidatesCertificateChain: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLAllowsExpiredCertificates: [NSNumber numberWithBool:NO],
(NSString *)kCFStreamSSLAllowsExpiredRoots: [NSNumber numberWithBool:NO],
(NSString *)kCFStreamSSLAllowsAnyRoot: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLCertificates: certificates,
(NSString *)kCFStreamSSLIsServer: [NSNumber numberWithBool:YES],
(NSString *)kCFStreamSSLLevel: (NSString *)kCFStreamSocketSecurityLevelTLSv1};
CFReadStreamSetProperty(readStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (CFTypeRef)settings);
然后我创建NSStream
流的实例并在另一个类中处理它们。
当我运行服务器并连接客户端时,我的NSStreamEventOpenCompleted
委托中得到了常规。如果我只是关闭连接,然后尝试写入流或事件,我收到以下错误:
2013-10-25 13:27:08.584 TCPServer[6435:303] CFNetwork SSLHandshake failed (-9800)
2013-10-25 13:27:08.584 TCPServer[6435:303] NSStreamEventOpenCompleted
2013-10-25 13:27:08.585 TCPServer[6435:303] NSStreamEventErrorOccurred
我想知道我必须在客户端实现什么。另外我想知道为什么在发送数据或从客户端断开连接时会出现握手失败。每当发生此错误时,客户端都会认为它仍然处于连接状态。
是否有任何好的 TCP SSL/TLS 教程或其他涵盖客户端和服务器端的材料?