GCDAsyncSocket startTLS 不起作用
GCDAsyncSocket startTLS does not work
我能够使用 IP 和端口连接到所需的套接字。
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port {
[sender startTLS:nil];
if(self.createTCPSocketHelperDelegate && @selector(returnConnectedTCPSocket:forNASWithMacAddress:))
{
[self.createTCPSocketHelperDelegate returnConnectedTCPSocket:sender forNASWithMacAddress:_macAddress];
}
}
我正在发送 TLS 设置字典 nil 因为它使用默认设置。
它给我的错误如下
Error Domain=kCFStreamErrorDomainSSL Code=-9806 "The operation couldn’t be completed. (kCFStreamErrorDomainSSL error -9806.)" UserInfo=0x17d92420 {NSLocalizedRecoverySuggestion=Error code definition can be found in Apple's SecureTransport.h}
我不明白那里出了什么问题。请帮助我提供一些连接到 SSL 服务器并使用 TCP/TLS 协议的示例代码。
帮助将不胜感激。先感谢您。 :)
我知道了。基本上我无法完成SSL握手,我找到了如下方法:
初始化GCDAsyncSocket套接字并连接IP和端口如下,
NSError *error;
_gcdAsyncTCPSocket = [[GCDAsyncSocket alloc] initWithDelegate:self
delegateQueue:dispatch_get_main_queue()];
_gcdAsyncTCPSocket.delegate = self;
_ipAddress = ipAddress;
_tcpPortNumber = portNumber;
if(![_gcdAsyncTCPSocket connectToHost:ipAddress onPort:portNumber withTimeout:30 error:&error])
{
if(self.createTCPSocketHelperDelegate && @selector(failedToCreateTCPSocket))
{
[self.createTCPSocketHelperDelegate failedToCreateTCPSocket];
}
}else {
NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
[settings setObject:[NSNumber numberWithBool:YES]
forKey:GCDAsyncSocketManuallyEvaluateTrust];
[_gcdAsyncTCPSocket startTLS:settings];
}
当您设置 GCDAsyncSocketManuallyEvaluateTrust 时,它会调用委托方法
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
我在其中用本地证书评估了服务器的自签名证书。如果等于则 completionHandler(YES) 否则 completionHandler(NO) 如下:
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler {
NSLog(@"didReceiveTrust");
//server certificate
SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(trust, 0);
CFDataRef serverCertificateData = SecCertificateCopyData(serverCertificate);
const UInt8* const serverData = CFDataGetBytePtr(serverCertificateData);
const CFIndex serverDataSize = CFDataGetLength(serverCertificateData);
NSData* cert1 = [NSData dataWithBytes:serverData length:(NSUInteger)serverDataSize];
//local certificate
NSString *localCertFilePath = [[NSBundle mainBundle] pathForResource:@"LocalCertificate" ofType:@"cer"];
NSData *localCertData = [NSData dataWithContentsOfFile:localCertFilePath];
CFDataRef myCertData = (__bridge CFDataRef)localCertData;
const UInt8* const localData = CFDataGetBytePtr(myCertData);
const CFIndex localDataSize = CFDataGetLength(myCertData);
NSData* cert2 = [NSData dataWithBytes:localData length:(NSUInteger)localDataSize];
if (cert1 == nil || cert2 == nil) {
NSLog(@"Certificate NULL");
completionHandler(NO);
return;
}
const BOOL equal = [cert1 isEqualToData:cert2];
if (equal) {
NSLog(@"Certificate match");
completionHandler(YES);
}else{
NSLog(@"Certificate not match");
completionHandler(NO);
}
}
如果证书与 completionHandler(YES) 匹配,它将调用委托
- (void)socketDidSecure:(GCDAsyncSocket *)sock {
NSLog(@"socketDidSecure");
_uploadSocket = sock;
//Do your stuff after this
}
希望它能对处理 SSL 和 GCDAsyncSocket 的人有所帮助。编码愉快!!
我能够使用 IP 和端口连接到所需的套接字。
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port {
[sender startTLS:nil];
if(self.createTCPSocketHelperDelegate && @selector(returnConnectedTCPSocket:forNASWithMacAddress:))
{
[self.createTCPSocketHelperDelegate returnConnectedTCPSocket:sender forNASWithMacAddress:_macAddress];
}
}
我正在发送 TLS 设置字典 nil 因为它使用默认设置。 它给我的错误如下
Error Domain=kCFStreamErrorDomainSSL Code=-9806 "The operation couldn’t be completed. (kCFStreamErrorDomainSSL error -9806.)" UserInfo=0x17d92420 {NSLocalizedRecoverySuggestion=Error code definition can be found in Apple's SecureTransport.h}
我不明白那里出了什么问题。请帮助我提供一些连接到 SSL 服务器并使用 TCP/TLS 协议的示例代码。
帮助将不胜感激。先感谢您。 :)
我知道了。基本上我无法完成SSL握手,我找到了如下方法:
初始化GCDAsyncSocket套接字并连接IP和端口如下,
NSError *error;
_gcdAsyncTCPSocket = [[GCDAsyncSocket alloc] initWithDelegate:self
delegateQueue:dispatch_get_main_queue()];
_gcdAsyncTCPSocket.delegate = self;
_ipAddress = ipAddress;
_tcpPortNumber = portNumber;
if(![_gcdAsyncTCPSocket connectToHost:ipAddress onPort:portNumber withTimeout:30 error:&error])
{
if(self.createTCPSocketHelperDelegate && @selector(failedToCreateTCPSocket))
{
[self.createTCPSocketHelperDelegate failedToCreateTCPSocket];
}
}else {
NSMutableDictionary *settings = [[NSMutableDictionary alloc] init];
[settings setObject:[NSNumber numberWithBool:YES]
forKey:GCDAsyncSocketManuallyEvaluateTrust];
[_gcdAsyncTCPSocket startTLS:settings];
}
当您设置 GCDAsyncSocketManuallyEvaluateTrust 时,它会调用委托方法
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
我在其中用本地证书评估了服务器的自签名证书。如果等于则 completionHandler(YES) 否则 completionHandler(NO) 如下:
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler {
NSLog(@"didReceiveTrust");
//server certificate
SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(trust, 0);
CFDataRef serverCertificateData = SecCertificateCopyData(serverCertificate);
const UInt8* const serverData = CFDataGetBytePtr(serverCertificateData);
const CFIndex serverDataSize = CFDataGetLength(serverCertificateData);
NSData* cert1 = [NSData dataWithBytes:serverData length:(NSUInteger)serverDataSize];
//local certificate
NSString *localCertFilePath = [[NSBundle mainBundle] pathForResource:@"LocalCertificate" ofType:@"cer"];
NSData *localCertData = [NSData dataWithContentsOfFile:localCertFilePath];
CFDataRef myCertData = (__bridge CFDataRef)localCertData;
const UInt8* const localData = CFDataGetBytePtr(myCertData);
const CFIndex localDataSize = CFDataGetLength(myCertData);
NSData* cert2 = [NSData dataWithBytes:localData length:(NSUInteger)localDataSize];
if (cert1 == nil || cert2 == nil) {
NSLog(@"Certificate NULL");
completionHandler(NO);
return;
}
const BOOL equal = [cert1 isEqualToData:cert2];
if (equal) {
NSLog(@"Certificate match");
completionHandler(YES);
}else{
NSLog(@"Certificate not match");
completionHandler(NO);
}
}
如果证书与 completionHandler(YES) 匹配,它将调用委托
- (void)socketDidSecure:(GCDAsyncSocket *)sock {
NSLog(@"socketDidSecure");
_uploadSocket = sock;
//Do your stuff after this
}
希望它能对处理 SSL 和 GCDAsyncSocket 的人有所帮助。编码愉快!!