过去,在用 Delphi 或 C++Builder 构建的 iOS 或 macOS 应用中部署 TLS,意味着要捆绑 OpenSSL:一个 libssl.dylib 和一个 libcrypto.dylib 随应用一起打包,并由你自己进行版本匹配和打补丁。sgcWebSockets 取消了这一要求。全新的原生 TLS 后端 iohAppleTLS 使用 Apple 自己的 TLS,因此你的应用可以安全连接,无需部署 OpenSSL .dylib。它在 Enterprise 版本中提供。
更妙的是,在现代系统上它还能为你提供 TLS 1.3。该后端会为设备自动选用最佳的系统 API,全部隐藏在单个设置之后,因此你无需根据 OS 版本进行分支判断,代码在各处都保持一致。
一行切换
TLS 后端通过 TLSOptions.IOHandler 选择。要使用 Apple 的原生 TLS,将其设置为 iohAppleTLS。你的其余网络代码无需改动。
uses
sgcWebSocket, sgcWebSocket_Types;
WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAppleTLS;
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;
在其他平台上,你可以继续使用合适的后端:iohOpenSSL 在任何地方都可用,iohSChannel 在 Windows 上是原生的,而 iohAndroidTLS 是 Android 上无需部署任何内容的原生选项。一个小小的条件判断就能让同一个客户端组件在每个目标平台上都正确无误。
WSClient.TLS := True;
{$IF Defined(IOS) or Defined(MACOS)}
WSClient.TLSOptions.IOHandler := iohAppleTLS; // native, no OpenSSL .dylib
{$ELSEIF Defined(ANDROID)}
WSClient.TLSOptions.IOHandler := iohAndroidTLS; // native, no OpenSSL .so
{$ELSEIF Defined(MSWINDOWS)}
WSClient.TLSOptions.IOHandler := iohSChannel; // native on Windows
{$ELSE}
WSClient.TLSOptions.IOHandler := iohOpenSSL; // OpenSSL elsewhere
{$ENDIF}
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;
无需部署 OpenSSL .dylib
使用原生后端,就无需捆绑、版本匹配或打补丁任何 OpenSSL。TLS 协议栈随操作系统一起提供,因此应用更加精简,也摆脱了第三方加密依赖。对于 App Store 提交而言,这同样意味着少了一个需要说明的原生库,而且你的 TLS 策略会跟随 Apple,而不是几个月前你冻结的某个库构建版本。安全修复会通过 OS 更新到达。
TLS 1.3 并自动回退
单个 iohAppleTLS 设置会为每台设备挑选合适的系统 API。在 macOS 10.14+ 和 iOS 12+ 上,它使用 Network.framework,从而带来 TLS 1.3。在较旧的系统上,它会回退到 Secure Transport,后者最高仅支持 TLS 1.2。你无需编写任何版本检查,后端会选择路径,而且你的代码在两种情形下都完全相同。
功能完整的 TLS 客户端
这是一个功能完整的客户端,而非精简版。它使用系统信任存储,执行 SNI 和主机名验证,并暴露一个 OnAppleTLSVerifyPeer 回调,使你可以自行检查证书并接受或拒绝它。你可以通过 RootCertFile 用自定义 CA 根证书信任一个私有颁发机构,通过 CertFile 和 Password 为双向 TLS 提供客户端证书,并通过 ALPN 公告诸如 http/1.1 之类的应用协议。
WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAppleTLS;
WSClient.TLSOptions.VerifyCertificate := True;
WSClient.TLSOptions.ALPNProtocols.Add('http/1.1');
WSClient.TLSOptions.RootCertFile := ''; // optional custom CA (PEM/DER)
WSClient.TLSOptions.CertFile := ''; // optional client cert (PKCS#12) for mTLS
WSClient.TLSOptions.Password := ''; // client cert password
WSClient.OnAppleTLSVerifyPeer := DoVerifyPeer; // optional custom validation
WSClient.Host := 'your.server.com';
WSClient.Port := 443;
WSClient.Active := True;
verify-peer 回调会向你提供证书主题及其 SHA-256 指纹、信任评估结果,以及一个由你设置以允许或阻止连接的 Accept 标志。这是固定证书(pin)或在系统信任决定之上应用你自己策略的天然位置。
与你已在使用的组件协同工作
该后端位于共享的 TLSOptions 之后,因此并不局限于 WebSocket 客户端。TCP 和 HTTP/2 客户端,以及其他暴露 TLSOptions 的组件,都以相同方式选用它。如果你的代码已经配置了 TLSOptions,那么启用原生 Apple TLS 只是一次赋值,连接或交换数据的方式都无需改变。
Android 上的相同理念
如果你同时面向 Android,配套的 iohAndroidTLS 后端在那里完成同样的工作:它通过平台的 SSLEngine 使用 Android 自己的 TLS,无需部署 OpenSSL .so。模式完全相同,你按平台挑选原生处理器。详情请见原生 Android TLS 页面。
可用性
原生 Apple TLS(iohAppleTLS)随 sgcWebSockets 的 Enterprise 版本提供。要全面了解这四个 TLS 后端,包括在每个平台上的 OpenSSL、Windows 上的 SChannel,以及原生 Android 和 Apple 处理器,请参阅 SSL / TLS 部分和原生 Apple TLS 页面。
可从 sgcWebSockets 下载页面下载,或通过 GetIt 或你的注册账户获取。
有疑问、反馈,或需要帮助将 iOS 或 macOS 应用迁离 OpenSSL?联系我们,你会收到编写这些代码的人的回复。
