用 Delphi 或 C++Builder 发布一个安全的 Android 应用,一直都意味着一件额外的麻烦事:要把 libssl.so 和 libcrypto.so 打包进 APK,以便运行时能用上 OpenSSL。sgcWebSockets 免去了这件麻烦事。一个新的原生 TLS 后端 iohAndroidTLS 把加密工作交给 Android 自身,因此你的应用通过 TLS 连接时无需部署任何 OpenSSL 库。该功能在 Enterprise 版本中提供。
在底层,该后端通过 JNI 驱动平台自带的 javax.net.ssl.SSLEngine。操作系统负责执行握手、记录加密和证书校验。sgcWebSockets 只是把明文输入进去,再取出密文,这意味着整个 TLS 栈正是 Google 随操作系统一起发布并打补丁的那一套。
一行代码即可切换
TLS 后端通过 TLSOptions.IOHandler 选择。要使用 Android 的原生 TLS,把它设为 iohAndroidTLS 即可。你的网络代码中的其他一切都保持不变。
uses
sgcWebSocket, sgcWebSocket_Types;
WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAndroidTLS;
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;
在其他平台上,你可以保留适合的后端:iohOpenSSL 在任何地方都能用,而 iohSChannel 是 Windows 上无需部署任何东西的原生选项。一小段条件编译就能让同一个客户端组件在每个目标平台上都保持正确。
WSClient.TLS := True;
{$IFDEF ANDROID}
WSClient.TLSOptions.IOHandler := iohAndroidTLS; // native, no OpenSSL .so
{$ELSE}
{$IFDEF MSWINDOWS}
WSClient.TLSOptions.IOHandler := iohSChannel; // native on Windows
{$ELSE}
WSClient.TLSOptions.IOHandler := iohOpenSSL; // OpenSSL elsewhere
{$ENDIF}
{$ENDIF}
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;
APK 中没有 OpenSSL
这正是核心优势所在。采用原生后端后,APK 中既不带 libssl.so,也不带 libcrypto.so。安装包更小,而且你再也不必去追逐某个 OpenSSL 版本、为了一份安全公告而重新编译,或者把某个库的构建版本与设备匹配起来。TLS 实现存在于设备之上,由 Android 维护,因此安全修复是通过系统更新到来的,而不是通过你的发布周期。
它还消除了一类部署问题。不会再有“找不到库”的情况,打包的 .so 与设备之间不会出现架构不匹配,也不会再有第二份加密代码需要审计。你只需设置一个属性,然后发布即可。
一个完整的 TLS 客户端,而非阉割版
这个原生后端是一个完整的客户端。它会用 Android 系统信任库来校验服务器并执行主机名验证,因此连接到公共证书颁发机构无需任何额外配置。它会协商 TLS 1.3,并在 Android 10(API 29)及以上版本支持 ALPN,让你能在握手期间通告诸如 http/1.1 之类的应用层协议。
由于它和其他每一个后端一样位于同一套 TLSOptions API 之后,那些熟悉的属性会照常工作。VerifyCertificate 用于打开或关闭对端校验,RootCertFile 用于信任一个私有颁发机构,CertFile 和 Password 用于出示客户端证书,ALPNProtocols 则列出要协商的协议。
WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAndroidTLS;
WSClient.TLSOptions.VerifyCertificate := True;
WSClient.TLSOptions.ALPNProtocols.Add('http/1.1'); // Android 10 (API 29)+
WSClient.Host := 'your.server.com';
WSClient.Port := 443;
WSClient.Active := True;
与你已在使用的组件协同工作
该后端接入了共享的 TLSOptions,因此它并不局限于 WebSocket 客户端。TCP 客户端、HTTP/2 客户端以及其他暴露 TLSOptions 的组件都以同样的方式选择它。如果你的代码已经设置了 TLSOptions,那么添加原生 Android TLS 只是一次赋值,无需改动你打开连接、发送或接收的方式。
在 Apple 上是同样的思路
如果你同时也面向 iOS 或 macOS,配套的 iohAppleTLS 后端在那里做着同样的工作:它使用 Apple 自带的 TLS,无需部署任何 OpenSSL .dylib,并通过 Network.framework 达到 TLS 1.3。模式完全一致,你只需为每个平台选择对应的原生处理器。详情可在 原生 Apple TLS 页面阅读。
可用性
原生 Android TLS(iohAndroidTLS)随 sgcWebSockets 的 Enterprise 版本一起发布。要完整了解这四个 TLS 后端,包括在每个平台上的 OpenSSL、Windows 上的 SChannel 以及原生的 Android 和 Apple 处理器,请参阅 SSL / TLS 部分 和 原生 Android TLS 页面。
可从 sgcWebSockets 下载页面 下载,或通过 GetIt 或你的已注册账户获取。
有疑问、反馈,或在把 Android 应用从 OpenSSL 迁移出来时需要帮助吗?与我们联系,你将收到编写这些代码的人的回复。
