SChannel Indy 服务器 Delphi

· 功能

多年来,在 Windows 上部署启用 TLS 的服务器的 Delphi 开发者面临同样的挑战:将正确的 OpenSSL 库捆绑到应用程序中。版本不匹配、运行时缺失 DLL 以及安全公告后的手动更新一直是生产环境中持续的摩擦源。

sgcWebSockets 2026.3.0 起,基于 Indy 的服务器组件——TsgcWebSocketServerTsgcWebSocketHTTPServer——可以使用 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 只需更改几个属性:

  1. 启用 SSL——将 SSL 属性设置为 True
  2. 选择 SChannel 作为 IOHandler——将 SSLOptions.IOHandler 设置为 iohSChannel
  3. 选择 TLS 版本——将 SSLOptions.Version 设置为所需版本。大多数部署推荐使用 tls1_2
  4. 设置端口——将 SSLOptions.PortPort 设置为监听端口(通常为 443)。
  5. 配置证书——通过 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(个人)、scsnRootscsnTrustscsnCA
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 端点。

重要说明