Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios GCDAsyncSocket startTLS不工作_Ios_Objective C_Iphone_Gcdasyncsocket_Starttls - Fatal编程技术网

Ios GCDAsyncSocket startTLS不工作

Ios GCDAsyncSocket startTLS不工作,ios,objective-c,iphone,gcdasyncsocket,starttls,Ios,Objective C,Iphone,Gcdasyncsocket,Starttls,我能够通过IP和端口连接到所需的插座 - (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port { [sender startTLS:nil]; if(self.createTCPSocketHelperDelegate && @selector(returnConnectedTCPSocket:forNASWithMacAddress

我能够通过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];
    }
}
我正在为nil发送TLS设置字典,因为它使用默认设置。 它给我的错误如下

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握手,我找到了如下方法:

- (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);
}
}
初始化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(是),否则completionHandler(否)如下所示:

- (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(是),它将调用委托

- (void)socketDidSecure:(GCDAsyncSocket *)sock {

NSLog(@"socketDidSecure");

_uploadSocket = sock;

//Do your stuff after this
}

希望它能帮助人们处理SSL和GCDAsyncSocket。快乐编码

我明白了。基本上我无法完成SSL握手,我找到了如下方法:

- (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);
}
}
初始化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(是),否则completionHandler(否)如下所示:

- (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(是),它将调用委托

- (void)socketDidSecure:(GCDAsyncSocket *)sock {

NSLog(@"socketDidSecure");

_uploadSocket = sock;

//Do your stuff after this
}

希望它能帮助人们处理SSL和GCDAsyncSocket。快乐编码

谢谢你的详细回答。有本地证书是绝对必要的吗?是否有其他不需要与保存的本地证书进行比较的路由?只有在服务器上有自签名证书时,才需要与本地证书进行比较。这个问题不涉及自签名证书,所以我认为这个答案与此无关。谢谢您提供的详细答案。有本地证书是绝对必要的吗?是否有其他不需要与保存的本地证书进行比较的路由?只有在服务器上有自签名证书时,才需要与本地证书进行比较。这个问题不涉及自签名证书,所以我认为这个答案不相关。