ssl - 如何在 IOS 中使用安全的 Ejabberd 服务器连接 XMPP 客户端?

标签 ssl xmppframework client-certificates gcdasyncsocket tls1.1

我正在开发聊天应用程序,其中我的 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/

相关文章:

ios - 不能添加有 parent 的 child ;先分离或复制

ssl - 如何在 logstash 配置中禁用 SSL?

ssl - Certbot 从 Nginx 将 HTTP 重定向到 HTTPS 不起作用

ssl - WSO2-emm : How can i create a BKS file that is compatible with Android?

ios - 在 XMPPFramework 和 Swift 2 中未调用 didReceiveInvitation()

git - OS X : Git with client certificates rejected

rest - 在 Flask Peewee 中使用 SSL 证书

ios - 使用 XMPP 的 Facebook 聊天室

java - axis2.AxisFault : [clientAuthRequired] Client certificate not found

c# - 从商店加载 X509Certificate2 证书链