带SSL的GCDAsyncSocket

时间:2013-08-20 06:36:13

标签: ssl gcdasyncsocket

我运行一个接受Socket或SSLSocket连接(不同端口)的Java服务器。在客户端,我在我的iPhone应用程序中使用GCDAsyncSocket连接到服务器。如果我使用不安全的版本(没有SSL),哪个工作正常。

现在我尝试使用SSL进行连接。这该怎么做?我完全不知道从哪里开始。我的问题:

1)我需要什么样的证书? Android应用程序可以使用.bks证书在同一台服务器上正常运行

2)如何将证书导入我的应用程序?我希望它稍后通过AppStore分发。我是否必须将证书文件放在应用程序的某个目录中?

3)我在哪里加载代码中的证书?有没有类似的方法 - (void)loadCertificate {    NSString * myCertificate = @“client.bks”;    ... }

4)我必须设置哪些参数来激活GCDAsyncSocket中的SSL,就像 BOOL useSSL = true; ...

5)假设回答问题1-4。现在怎么办?如何启动与服务器的连接?哪个构造函数与哪个参数一起使用?

如果有人问“为什么使用SSLSocket而不是......”。因为服务器已经存在,并且它可以很好地与Android应用程序一起工作。

感谢您的帮助!

1 个答案:

答案 0 :(得分:7)

这是一个老问题,但我希望它会帮助别人。

  1. 我更喜欢pfx,但我认为bks也会没问题。
  2. 是的,您需要将这些证书捆绑在一起。
  3. 您需要在didConnectToHost方法中设置SSL设置。
  4. [sock startTLS:sslSettings];
  5. 最后在CocoaAsyncSocket文件夹中有一个名为ConnectTest的示例应用程序,您应首先检查it

    NSMutableDictionary *sslSettings = [[NSMutableDictionary alloc] init];
            NSData *pkcs12data = [[NSData alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"client" ofType:@"bks"]];
            CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(pkcs12data);
            CFStringRef password = CFSTR("YOUR PASSWORD");
            const void *keys[] = { kSecImportExportPassphrase };
            const void *values[] = { password };
            CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
    
            CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    
            OSStatus securityError = SecPKCS12Import(inPKCS12Data, options, &items);
            CFRelease(options);
            CFRelease(password);
    
            if(securityError == errSecSuccess)
                NSLog(@"Success opening p12 certificate.");
    
            CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
            SecIdentityRef myIdent = (SecIdentityRef)CFDictionaryGetValue(identityDict,
                                                                          kSecImportItemIdentity);
    
            SecIdentityRef  certArray[1] = { myIdent };
            CFArrayRef myCerts = CFArrayCreate(NULL, (void *)certArray, 1, NULL);
    
            [sslSettings setObject:(id)CFBridgingRelease(myCerts) forKey:(NSString *)kCFStreamSSLCertificates];
            [sslSettings setObject:NSStreamSocketSecurityLevelNegotiatedSSL forKey:(NSString *)kCFStreamSSLLevel];
            [sslSettings setObject:(id)kCFBooleanTrue forKey:(NSString *)kCFStreamSSLAllowsAnyRoot];
            [sslSettings setObject:@"CONNECTION ADDRESS" forKey:(NSString *)kCFStreamSSLPeerName];
            [sock startTLS:sslSettings];