SChannel Indy Server Delphi

· 기능

오랫동안 Windows에서 TLS 지원 서버를 배포하는 Delphi 개발자들은 동일한 과제에 직면해 왔어요: 애플리케이션에 올바른 OpenSSL 라이브러리를 번들로 포함시키는 것이에요. 버전 불일치, 런타임 시 누락된 DLL, 보안 권고 후 수동 업데이트가 프로덕션 환경에서 지속적인 마찰 원인이 됐어요.

sgcWebSockets 2026.3.0부터 Indy 기반 서버 컴포넌트인 TsgcWebSocketServerTsgcWebSocketHTTPServer는 TLS 공급자로 Windows SChannel(Secure Channel)을 사용할 수 있어요. SChannel은 모든 Windows 버전에 내장된 네이티브 Windows TLS 구현이에요. 외부 DLL이 필요 없고, Windows 인증서 저장소와 직접 통합되며, Windows 업데이트를 통해 자동으로 보안 패치를 받아요.

이 글에서는 Delphi 애플리케이션에서 SChannel 기반 서버를 설정하고 배포하는 방법을 안내해요.

서버 측에서 SChannel을 사용하는 이유

SChannel은 Windows 서버의 TLS와 관련된 가장 일반적인 배포 문제를 해결해요.

외부 종속성 없음
SChannel은 Windows에 내장되어 있어요. libeay32.dll, ssleay32.dll, libcrypto, libssl이 필요 없어요. 설치 파일이 작아지고 배포가 간단해져요.
Windows 인증서 저장소
운영 체제가 이미 설치하고 관리하는 인증서를 사용해요. PEM 파일을 복사할 필요 없이 인증서를 지문으로 참조하면 돼요.
자동 보안 업데이트
TLS 개선 사항과 보안 패치가 Windows 업데이트를 통해 적용돼요. 수동 라이브러리 업그레이드나 OpenSSL CVE 재배포가 필요 없어요.

빠른 시작 — 5단계

서버에서 SChannel을 활성화하려면 몇 가지 속성만 변경하면 돼요:

  1. SSL 활성화SSL 속성을 True로 설정하세요.
  2. IOHandler로 SChannel 선택SSLOptions.IOHandleriohSChannel로 설정하세요.
  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자 16진수 지문을 복사하세요.

서버 설정

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 개인 키가 포함된 서버 인증서
Root scsnRoot 신뢰할 수 있는 루트 인증 기관
Trust 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 인증서와 개인 키를 변환하세요:

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

SChannel_Options 참조

SSLOptions.SChannel_Options 하위 속성은 모든 SChannel 전용 서버 설정을 제공해요.

속성 유형 설명
CertHash String Windows 인증서 저장소에 설치된 인증서의 40자 16진수 지문이에요.
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 업데이트를 통해 안전한 기본 세트를 유지하므로 대부분의 배포에 적합해요.

주의. 암호를 너무 엄격하게 제한하면 일부 클라이언트가 연결하지 못할 수 있어요. 프로덕션에 커스텀 암호 목록을 배포하기 전에 예상 클라이언트를 대상으로 충분히 테스트하세요.

레거시 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 vs. OpenSSL — 언제 무엇을 사용해야 할까요

두 TLS 공급자 모두 완전히 지원돼요. 올바른 선택은 배포 플랫폼과 운영 요구 사항에 따라 달라요.

기능 SChannel OpenSSL
외부 DLL 필요 여부 아니요
Windows Certificate Store 네이티브 지원하지 않아요
자동 보안 업데이트 예 (Windows 업데이트) 수동 라이브러리 업데이트
크로스플랫폼 Windows 전용 Windows, Linux, macOS
인증서 형식 PFX + Windows Store PEM, PFX
TLS 1.0 – 1.3 Yes Yes

결론. 서버가 Windows에서만 실행된다면 SChannel이 더 간단하고 유지 관리가 쉬운 선택이에요. 크로스 플랫폼 지원이 필요한 경우 iohOpenSSL을 사용하세요. 두 공급자 간 전환은 IOHandler 속성만 변경하면 되고 다른 코드 변경은 필요 없어요.

전체 예제: 보안 WebSocket 서버

Windows 인증서 저장소의 인증서를 사용해 SChannel로 완전히 설정된 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 엔드포인트에 가장 적합해요.

중요 사항