我正在开发聊天应用程序,其中我的 Ejabbered 服务器使用 SSL 是安全的 和 TLSv1.1/1.2,我正在尝试将客户端连接到服务器,但出现以下错误代码。
Error Domain=GCDAsyncSocketErrorDomain Code=7 "Socket closed by remote peer" UserInfo={NSLocalizedDescription=Socket closed by remote peer.
必需的设置 在 Appdelegate (Setupstream) 中
_xmppStream.hostName=@""; // hostname
_xmppStream.hostPort=5223; // 5223 for secure SSL connection
_xmppStream.startTLSPolicy = XMPPStreamStartTLSPolicyRequired;
customCertEvaluation = YES;
之后手动信任自定义证书验证
- (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:
(NSMutableDictionary *)settings{
NSString *expectedCertName = [_xmppStream.myJID domain];
if (expectedCertName){
[settings setObject:expectedCertName forKey:(NSString *)kCFStreamSSLPeerName];
}
if (customCertEvaluation){
[settings setObject:@(YES)forKey:GCDAsyncSocketManuallyEvaluateTrust];
}
然后在 completionHandler 中匹配客户端服务器证书。
-(void)xmppStream:(XMPPStream *)sender didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler{
SecCertificateRef certificate=SecTrustGetCertificateAtIndex(trust, 0);
NSLog(@"serverCertificate :%@",certificate);
NSData *certData1=(__bridge NSData *)SecCertificateCopyData(certificate);
// Get our certificate
NSString *cer = [NSString stringWithFormat:@"%@", [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"crt"]];
NSData *certData2 = [[NSData alloc] initWithContentsOfFile:cer];
OSStatus status = -1;
SecTrustResultType result = kSecTrustResultDeny;
if(certData1 && certData2){
SecCertificateRef cert1;
cert1 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData1);
SecCertificateRef cert2;
cert2 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certData2);
const void *ref[] = {cert1, cert2};
CFArrayRef ary = CFArrayCreate(NULL, ref, 2, NULL);
SecTrustSetAnchorCertificates(trust, ary);
status = SecTrustEvaluate(trust, &result);
}
else{
NSLog(@"local certificates could not be loaded");
completionHandler(NO);
}
if ((status == noErr && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified))){
completionHandler(YES);
NSLog(@"Certificate match");
}
else{
arrayRefTrust = SecTrustCopyProperties(trust);
NSLog(@"error in connection occured\n%@", arrayRefTrust);
completionHandler(NO);
NSLog(@"Certificate not match");
}
}
是否需要在 GCDAsyncSocket.m/XMPPStream.m 类中进行任何自定义以实现安全连接。
最佳答案
尝试使用这个已弃用的方法:
[self.xmppStream oldSchoolSecureConnectWithTimeout:60.f error:&connectionError]
还要确保您正确设置了主机名:
[self.xmppStream setHostName:@"yourhostname.com"]
不使用 https
作为前缀。
目前我们正在使用此解决方法,同时我们找到了一种无需弃用的连接方法即可工作的方法。
关于ssl - 如何在 IOS 中使用安全的 Ejabberd 服务器连接 XMPP 客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47279427/