【发布时间】:2013-10-25 12:46:05
【问题描述】:
我有一个简单的 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 教程或其他涵盖客户端和服务器端的材料?
【问题讨论】:
-
您是否在连接的两端使用相同的代码?如果是这样,那么看起来您正在将连接两侧的
kCFStreamSSLIsServer属性设置为YES。 -
我现在不在办公室。但这可能是对的。然后我应该删除
kCFStreamSSLIsServer吗? -
我认为您希望保留这行代码 - 在作为服务器的连接一侧,保持原样。但在客户端,您需要将此值设置为字典中的
NO。 -
抱歉,我现在不确定。我做了几个 TCP 测试和 edu 项目……但我认为你应该试一试,当你为此苦苦挣扎时。
标签: objective-c sockets ssl tcp nsstream