多年来,在 Windows 上部署启用 TLS 的服务器的 Delphi 开发者面临同样的挑战:将正确的 OpenSSL 库捆绑到应用程序中。版本不匹配、运行时缺失 DLL 以及安全公告后的手动更新一直是生产环境中持续的摩擦源。
从 sgcWebSockets 2026.3.0 起,基于 Indy 的服务器组件——TsgcWebSocketServer 和 TsgcWebSocketHTTPServer——可以使用 Windows SChannel(安全通道)作为 TLS 提供程序。SChannel 是内置于所有 Windows 版本的原生 TLS 实现,无需外部 DLL,直接与 Windows 证书存储集成,并通过 Windows Update 自动接收安全补丁。
本文介绍如何在 Delphi 应用程序中配置和部署基于 SChannel 的服务器。
为什么在服务器端使用 SChannel?
SChannel 消除了 Windows 服务器上与 TLS 相关的最常见部署难题。
|
零外部依赖 SChannel 内置于 Windows 中,无需 libeay32.dll、ssleay32.dll、libcrypto 或 libssl。安装包更小,部署更简单。 |
Windows 证书存储 使用操作系统已安装和管理的证书,无需复制 PEM 文件,只需通过指纹引用证书。 |
自动安全更新 TLS 改进和安全补丁通过 Windows Update 应用。无需手动升级库,也无需因 OpenSSL CVE 重新部署。 |
快速入门——5 个步骤
在服务器上启用 SChannel 只需更改几个属性:
- 启用 SSL——将
SSL属性设置为True。 - 选择 SChannel 作为 IOHandler——将
SSLOptions.IOHandler设置为iohSChannel。 - 选择 TLS 版本——将
SSLOptions.Version设置为所需版本。大多数部署推荐使用tls1_2。 - 设置端口——将
SSLOptions.Port和Port设置为监听端口(通常为 443)。 - 配置证书——通过 Windows 证书存储(指纹)或 PFX 文件提供证书。
方法 1:从 Windows 证书存储获取证书
如果您的证书已安装在 Windows 证书存储中,只需提供其指纹即可。这是生产服务器和 Windows 服务的推荐方式。
查找证书指纹
打开 PowerShell 并列出本地机器个人存储中的证书:
PS C:\> dir cert:\localmachine\my
Directory: Microsoft.PowerShell.Security\Certificate::localmachine\my
Thumbprint Subject
---------- -------
C12A8FC8AE668F866B48F23E753C93D357E9BE10 CN=*.mydomain.com
A7F3D2E1B9C84A6D5E0F123456789ABCDEF01234 CN=api.mydomain.com
复制要使用的证书的 40 字符十六进制指纹。
配置服务器
var
oServer: TsgcWebSocketHTTPServer;
begin
oServer := TsgcWebSocketHTTPServer.Create(nil);
// Enable TLS with SChannel
oServer.SSL := True;
oServer.SSLOptions.IOHandler := iohSChannel;
oServer.SSLOptions.Version := tls1_2;
oServer.SSLOptions.Port := 443;
oServer.Port := 443;
// Point to the certificate in the Windows Store
oServer.SSLOptions.SChannel_Options.CertHash :=
'C12A8FC8AE668F866B48F23E753C93D357E9BE10';
oServer.SSLOptions.SChannel_Options.CertStoreName := scsnMY;
oServer.SSLOptions.SChannel_Options.CertStorePath := scspStoreLocalMachine;
// Start listening
oServer.Active := True;
end;
生产提示:对于作为 Windows 服务部署的服务器,始终使用 scspStoreLocalMachine。无论哪个用户账户运行服务,本地机器存储都可访问,而 scspStoreCurrentUser 与已登录用户的配置文件绑定。
证书存储选项
| 存储名称 | 常量 | 内容 |
|---|---|---|
| 个人(MY) | scsnMY |
带私钥的服务器证书 |
| 根 | scsnRoot |
受信任的根证书颁发机构 |
| 信任 | scsnTrust |
受信任的证书 |
| CA | scsnCA |
中间证书颁发机构 |
方法 2:从 PFX 文件获取证书
如果您有 PFX(.pfx 或 .p12)证书文件,可以直接加载,无需安装到 Windows 证书存储中。SChannel 将在服务器启动时导入证书。
var
oServer: TsgcWebSocketHTTPServer;
begin
oServer := TsgcWebSocketHTTPServer.Create(nil);
// Enable TLS with SChannel
oServer.SSL := True;
oServer.SSLOptions.IOHandler := iohSChannel;
oServer.SSLOptions.Version := tls1_2;
oServer.SSLOptions.Port := 443;
oServer.Port := 443;
// Load certificate from a PFX file
oServer.SSLOptions.CertFile := 'c:\certificates\server.pfx';
oServer.SSLOptions.Password := 'mypassword';
// Start listening
oServer.Active := True;
end;
有 PEM 文件?SChannel 仅接受 PFX 格式。使用一条命令将 PEM 证书和私钥转换为 PFX:
openssl pkcs12 -inkey server.key -in server.crt -export -out server.pfx
SChannel_Options 参考
SSLOptions.SChannel_Options 子属性公开了所有 SChannel 特定的服务器设置。
| 属性 | 类型 | 描述 |
|---|---|---|
| CertHash | String | Windows 证书存储中已安装证书的 40 字符十六进制指纹。 |
| CertStoreName | Enum | 搜索哪个存储:scsnMY(个人)、scsnRoot、scsnTrust、scsnCA。 |
| CertStorePath | Enum | 存储位置:scspStoreLocalMachine(推荐)或 scspStoreCurrentUser。 |
| CipherList | String | 允许的密码算法冒号分隔列表(如 CALG_AES_256:CALG_AES_128)。留空使用 Windows 默认值。 |
| UseLegacyCredentials | Boolean | 为 True 时使用旧版 SCHANNEL_CRED 结构。适用于 Windows Server 2019 及更早版本。 |
TLS 版本配置
通过 SSLOptions.Version 属性控制服务器接受哪个 TLS 协议版本。
| 值 | 协议 | 建议 |
|---|---|---|
tls1_3 |
TLS 1.3 | 最佳安全性。所有客户端都支持时使用。 |
tls1_2 |
TLS 1.2 | 大多数生产部署推荐使用。 |
tls1_1 |
TLS 1.1 | 旧版协议,除非旧客户端需要否则避免使用。 |
tls1_0 |
TLS 1.0 | 已弃用,不推荐使用。 |
tlsUndefined |
TLS 1.0 – 1.2 | 接受 TLS 1.0、1.1 或 1.2 中的任意一种。 |
// Enforce TLS 1.2 minimum for modern security
oServer.SSLOptions.Version := tls1_2;
// Or use TLS 1.3 for the strongest encryption
oServer.SSLOptions.Version := tls1_3;
密码套件配置
默认情况下,SChannel 使用 Windows 管理的系统级密码配置。对于需要更严格控制的环境,您可以限制允许的算法。
// Restrict to AES-256 and AES-128 only
oServer.SSLOptions.SChannel_Options.CipherList :=
'CALG_AES_256:CALG_AES_128';
将 CipherList 属性留空以接受 Windows 默认密码配置。这适用于大多数部署,因为 Windows 维护着通过 Windows Update 更新的安全默认集。
注意:过于激进地限制密码套件可能导致某些客户端无法连接。在生产环境部署自定义密码套件列表之前,请针对预期客户端群充分测试。
旧版 Windows 兼容性
组件默认使用现代 SCH_CREDENTIALS API。在不支持此 API 的旧版 Windows(Server 2019 及更早版本)上,可以回退到旧版凭据结构。
// Enable legacy mode for Windows Server 2019 and earlier
oServer.SSLOptions.SChannel_Options.UseLegacyCredentials := True;
大多数情况下,组件会自动检测 Windows 版本并选择合适的 API。仅当服务器在旧版 Windows 上无法启动时才使用 UseLegacyCredentials 属性。
SChannel 与 OpenSSL——何时选用
两种 TLS 提供程序均完全支持。正确的选择取决于您的部署平台和运营需求。
| 特性 | SChannel | OpenSSL |
|---|---|---|
| 需要外部 DLL | 否 | 是 |
| Windows 证书存储 | 原生支持 | 不支持 |
| 自动安全更新 | 是(Windows Update) | 手动更新库 |
| 跨平台 | 仅 Windows | Windows、Linux、macOS |
| 证书格式 | PFX + Windows 存储 | PEM、PFX |
| TLS 1.0 – 1.3 | 是 | 是 |
结论:如果您的服务器仅在 Windows 上运行,SChannel 是更简单、更易维护的选择。如果需要跨平台支持,请使用 iohOpenSSL。在两者之间切换只需更改 IOHandler 属性,无需其他代码更改。
完整示例:安全 WebSocket 服务器
使用 SChannel 和 Windows 证书存储中证书的完整配置 WebSocket 服务器。
uses
sgcWebSocket_Server, sgcWebSocket_Classes;
var
oServer: TsgcWebSocketHTTPServer;
begin
oServer := TsgcWebSocketHTTPServer.Create(nil);
Try
// Server configuration
oServer.Port := 443;
// TLS configuration with SChannel
oServer.SSL := True;
oServer.SSLOptions.IOHandler := iohSChannel;
oServer.SSLOptions.Version := tls1_2;
oServer.SSLOptions.Port := 443;
// Certificate from Windows Certificate Store
oServer.SSLOptions.SChannel_Options.CertHash :=
'C12A8FC8AE668F866B48F23E753C93D357E9BE10';
oServer.SSLOptions.SChannel_Options.CertStoreName := scsnMY;
oServer.SSLOptions.SChannel_Options.CertStorePath := scspStoreLocalMachine;
// Assign WebSocket event handlers
oServer.OnConnect := OnClientConnect;
oServer.OnDisconnect := OnClientDisconnect;
oServer.OnMessage := OnClientMessage;
// Start the server
oServer.Active := True;
WriteLn('Secure WebSocket server listening on port 443 (SChannel TLS 1.2)');
WriteLn('Press Enter to stop...');
ReadLn;
Finally
oServer.Active := False;
oServer.Free;
End;
end;
适用于两种服务器组件
SChannel 在两种基于 Indy 的服务器组件上均可用,配置方式相同。
| 组件 | 描述 |
|---|---|
TsgcWebSocketHTTPServer |
内置 HTTP 服务器的 WebSocket 服务器,适合 WebSocket + REST API 组合使用。 |
TsgcWebSocketServer |
基于 Indy TCP 的纯 WebSocket 服务器,最适合专用 WebSocket 端点。 |
重要说明
- 仅限 Windows:SChannel 是 Windows API。对于跨平台服务器(Linux、macOS),请使用 OpenSSL(
iohOpenSSL)。 - 需要私钥:服务器证书必须包含私钥。使用 Windows 证书存储方法时,证书必须已连同私钥一起导入。
- 仅限 PFX 格式:SChannel 接受 PFX(.pfx / .p12)证书文件。如有 PEM 文件,请先使用
openssl pkcs12命令将其转换为 PFX。 - 服务使用本地机器存储:对于生产服务器,使用
scspStoreLocalMachine,使证书无论以哪个用户账户运行均可访问。 - 版本可用性:服务器端 SChannel 在 sgcWebSockets 的专业版、企业版和全访问版中可用。
