3

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

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

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

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

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

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

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

如果有人问“为什么使用 SSLSocket 而不是……”。因为服务器已经在那里,并且它与 Android 应用程序配合得很好。

谢谢您的帮助!

4

1 回答 1

7

这是一个老问题,但我希望它对其他人有所帮助。

  1. 我更喜欢 pfx,但我认为 bks 也可以。
  2. 是的,您需要将该证书放入捆绑包中。
  3. 您需要在 didConnectToHost 方法中设置 SSL 设置。
  4. [袜子开始TLS: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];
于 2013-09-24T06:28:04.427 回答