SChannel en servidor Indy de Delphi

· Características

Durante años, los desarrolladores Delphi que despliegan servidores con TLS en Windows se han enfrentado al mismo reto: empaquetar las librerías OpenSSL correctas con su aplicación. Las discrepancias de versión, las DLLs ausentes en tiempo de ejecución y las actualizaciones manuales tras avisos de seguridad han sido una fuente constante de fricción en entornos de producción.

Desde sgcWebSockets 2026.3.0, los componentes de servidor basados en Indy — TsgcWebSocketServer y TsgcWebSocketHTTPServer — pueden usar Windows SChannel (Secure Channel) como proveedor TLS. SChannel es la implementación nativa de TLS de Windows incluida en todas las versiones del sistema. No requiere DLLs externas, se integra directamente con el Almacén de certificados de Windows y recibe parches de seguridad automáticamente a través de Windows Update.

Este artículo recorre cómo configurar y desplegar servidores basados en SChannel en tus aplicaciones Delphi.

¿Por qué SChannel en el lado del servidor?

SChannel elimina los quebraderos de cabeza más habituales del despliegue de TLS en servidores Windows.

Cero dependencias externas
SChannel está integrado en Windows. Ni libeay32.dll, ni ssleay32.dll, ni libcrypto, ni libssl. Tu instalador se reduce y tu despliegue se simplifica.
Almacén de certificados de Windows
Usa los certificados ya instalados y gestionados por el sistema operativo. Sin necesidad de andar copiando archivos PEM — basta con referenciar el certificado por su thumbprint.
Actualizaciones de seguridad automáticas
Las mejoras de TLS y los parches de seguridad se aplican mediante Windows Update. Sin actualizaciones manuales de librerías, sin redespliegues por CVEs de OpenSSL.

Inicio rápido — 5 pasos

Habilitar SChannel en tu servidor solo requiere unos pocos cambios de propiedades:

  1. Habilita SSL — Establece la propiedad SSL a True.
  2. Selecciona SChannel como IOHandler — Establece SSLOptions.IOHandler a iohSChannel.
  3. Elige una versión de TLS — Establece SSLOptions.Version a la versión deseada. tls1_2 es recomendable para la mayoría de despliegues.
  4. Establece el puerto — Establece SSLOptions.Port y Port al puerto de escucha (típicamente 443).
  5. Configura el certificado — Proporciona un certificado a través del Almacén de certificados de Windows (thumbprint) o un archivo PFX.

Método 1: certificado desde el Almacén de Windows

Si tu certificado ya está instalado en el Almacén de certificados de Windows, solo necesitas proporcionar su thumbprint. Este es el enfoque recomendado para servidores de producción y servicios de Windows.

Encontrar el thumbprint del certificado

Abre PowerShell y lista los certificados del almacén personal Local Machine:

PS C:\> dir cert:\localmachine\my
Directory: Microsoft.PowerShell.Security\Certificate::localmachine\my
Thumbprint                                Subject
----------                                -------
C12A8FC8AE668F866B48F23E753C93D357E9BE10  CN=*.mydomain.com
A7F3D2E1B9C84A6D5E0F123456789ABCDEF01234  CN=api.mydomain.com

Copia el thumbprint hexadecimal de 40 caracteres del certificado que quieras usar.

Configurar el servidor

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;

Consejo para producción. Usa siempre scspStoreLocalMachine para servidores desplegados como servicios de Windows. El almacén Local Machine es accesible independientemente de qué cuenta de usuario ejecute el servicio, mientras que scspStoreCurrentUser está ligado al perfil del usuario que ha iniciado sesión.

Opciones de almacén de certificados

Nombre del almacén Constante Contiene
Personal (MY) scsnMY Certificados de servidor con claves privadas
Root scsnRoot Autoridades de certificación raíz de confianza
Trust scsnTrust Certificados de confianza
CA scsnCA Autoridades de certificación intermedias

Método 2: certificado desde un archivo PFX

Si tienes un archivo de certificado PFX (.pfx o .p12), puedes cargarlo directamente sin instalarlo en el Almacén de certificados de Windows. SChannel importará el certificado al arrancar el servidor.

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;

¿Tienes archivos PEM? SChannel solo acepta el formato PFX. Convierte tu certificado y clave privada PEM con un único comando:

openssl pkcs12 -inkey server.key -in server.crt -export -out server.pfx

Referencia de SChannel_Options

La subpropiedad SSLOptions.SChannel_Options expone todos los ajustes específicos de SChannel para el servidor.

Propiedad Tipo Descripción
CertHash String El thumbprint hexadecimal de 40 caracteres de un certificado instalado en el Almacén de certificados de Windows.
CertStoreName Enum En qué almacén buscar: scsnMY (Personal), scsnRoot, scsnTrust, scsnCA.
CertStorePath Enum Ubicación del almacén: scspStoreLocalMachine (recomendado) o scspStoreCurrentUser.
CipherList String Lista separada por dos puntos de los algoritmos de cifrado permitidos (p. ej. CALG_AES_256:CALG_AES_128). Déjala vacía para usar los valores por defecto de Windows.
UseLegacyCredentials Boolean Cuando es True, usa la estructura legacy SCHANNEL_CRED. Habilítalo en Windows Server 2019 y anteriores.

Configuración de la versión de TLS

Controla qué versión del protocolo TLS acepta el servidor mediante la propiedad SSLOptions.Version.

Valor Protocolo Recomendación
tls1_3 TLS 1.3 Mayor seguridad. Úsalo cuando todos los clientes lo soporten.
tls1_2 TLS 1.2 Recomendado para la mayoría de los despliegues de producción.
tls1_1 TLS 1.1 Legacy. Evítalo a menos que lo requieran clientes antiguos.
tls1_0 TLS 1.0 Obsoleto. No recomendado.
tlsUndefined TLS 1.0 – 1.2 Acepta cualquiera de TLS 1.0, 1.1 o 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;

Configuración de la suite de cifrado

Por defecto, SChannel usa la configuración de cifrados a nivel de sistema gestionada por Windows. Para entornos que requieren un control más estricto, puedes restringir los algoritmos permitidos.

// Restrict to AES-256 and AES-128 only
oServer.SSLOptions.SChannel_Options.CipherList :=
  'CALG_AES_256:CALG_AES_128';

Deja la propiedad CipherList vacía para aceptar la configuración de cifrados por defecto de Windows. Es lo adecuado para la mayoría de los despliegues, ya que Windows mantiene un conjunto seguro por defecto que se actualiza mediante Windows Update.

Precaución. Restringir los cifrados demasiado puede impedir que algunos clientes se conecten. Prueba a fondo con tu base de clientes esperada antes de desplegar listas de cifrados personalizadas en producción.

Compatibilidad con Windows legacy

El componente usa la API moderna SCH_CREDENTIALS por defecto. En versiones antiguas de Windows (Server 2019 y anteriores) que no soportan esta API, puedes volver a la estructura legacy de credenciales.

// Enable legacy mode for Windows Server 2019 and earlier
oServer.SSLOptions.SChannel_Options.UseLegacyCredentials := True;

En la mayoría de los casos, el componente detecta la versión de Windows automáticamente y selecciona la API adecuada. Usa la propiedad UseLegacyCredentials solo si el servidor no arranca en una versión antigua de Windows.

SChannel frente a OpenSSL — cuándo usar cada uno

Ambos proveedores TLS están totalmente soportados. La elección correcta depende de tu plataforma de despliegue y de tus requisitos operativos.

Característica SChannel OpenSSL
Requiere DLLs externas No
Almacén de certificados de Windows Nativo No soportado
Actualizaciones de seguridad automáticas Sí (Windows Update) Actualización manual de la librería
Multiplataforma Solo Windows Windows, Linux, macOS
Formatos de certificado PFX + Almacén de Windows PEM, PFX
TLS 1.0 – 1.3

En resumen. Si tu servidor se ejecuta exclusivamente en Windows, SChannel es la opción más sencilla y mantenible. Si necesitas soporte multiplataforma, usa iohOpenSSL. Cambiar entre ambos solo requiere modificar la propiedad IOHandler — no se necesita ningún otro cambio de código.

Ejemplo completo: servidor WebSocket seguro

Un servidor WebSocket totalmente configurado usando SChannel con un certificado del Almacén de certificados de Windows.

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;

Funciona con ambos componentes de servidor

SChannel está disponible en ambos componentes de servidor basados en Indy. La configuración es idéntica.

Componente Descripción
TsgcWebSocketHTTPServer Servidor WebSocket con servidor HTTP integrado. Ideal para APIs combinadas WebSocket + REST.
TsgcWebSocketServer Servidor WebSocket puro basado en Indy TCP. Ideal para endpoints WebSocket dedicados.

Notas importantes