1

我想在 iOS 应用程序中实现STARTTLS,但我无法从文档中弄清楚如何去做。

到目前为止,我有:

  • 我创建套接字CFStreamCreatePairWithSocketToHost并打开流:

     CFStreamCreatePairWithSocketToHost(
             NULL, (__bridge CFStringRef)host, port,
             &read_stream, &write_stream
     );
    
     reader = objc_retainedObject(read_stream);
     [ reader setDelegate:self ];
     [ reader scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode ];
     [ reader open ];
    
     writer = objc_retainedObject(write_stream);
     [ writer setDelegate:self ];
     [ writer scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode ];
     [ writer open ];
    
  • 当数据流上可用时,我得到正确的回调,因此连接正常。

  • 我成功地以纯文本方式与服务器交互并协商 STARTTLS。

  • 最终,服务器发送对 STARTTLS 的许可:

     . OK Begin TLS negotiation now.
    

现在是时候将套接字形式的明文升级为 TLS。接下来我该怎么做?

我认为我应该按照Apple 的文档执行此操作:

[ reader setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey ];
[ writer setProperty:NSStreamSocketSecurityLevelNegotiatedSSL forKey:NSStreamSocketSecurityLevelKey ];

但这似乎没有任何作用。我对它不起作用并不感到惊讶,因为文档说得很清楚:

您必须在打开流之前设置属性。

当然,在这种情况下,流必须已经打开,因为它用于进行明文 STARTTLS 协商!

我找不到任何有关如何将套接字从纯文本升级到 SSL 的文档,或者可能如何在一组输入和输出纯文本流之上分层一组新的 SSL 加密流。

4

1 回答 1

1

我找不到使用高级CFStream API 实现 STARTTLS 的任何方法。有CFStreamCreatePairWithSocket允许您连接自己的套接字,然后对其应用 TLS,但无法让库根据证书主机名验证远程主机名。

这样做的唯一方法似乎是使用这个级别低得多的库:安全传输参考

于 2015-07-08T12:29:01.640 回答