GCDAsyncSocket与SSL的配合使用

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

现在我尝试使用SSL连接。如何做到这一点?我完全不知道从哪里开始。我的问题是:

1)我需要什么样的证书?使用.bks证书的Android应用程序可以与相同的服务器很好地配合使用

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

3)在代码中加载证书的位置在哪里?是否有类似于 - (void)loadCertificate { NSString *myCertificate = @"client.bks"; ... }的方法?

4)我必须设置哪些参数才能在GCDAsyncSocket中激活SSL,例如 BOOL useSSL = true; ...

5)假设问题1-4已经得到解答。现在怎么办?如何启动与服务器的连接?使用哪个构造函数以及哪些参数?

如果有人问“为什么使用SSLSocket而不是...”。因为服务器已经存在,并且使用Android应用程序非常好。

感谢您的帮助!

1个回答

7
这是一个旧问题,但我希望它能帮助到其他人。
  1. 我更喜欢使用pfx格式,但我认为bks也可以。
  2. 是的,你需要将证书放入bundle中。
  3. 你需要在didConnectToHost方法中设置SSL设置。
  4. [sock startTLS:sslSettings];
最后,在CocoaAsyncSocket文件夹中有一个名为ConnectTest的示例应用程序,你应该先检查
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];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接