오랫동안 Windows에서 TLS 지원 서버를 배포하는 Delphi 개발자들은 동일한 과제에 직면해 왔어요: 애플리케이션에 올바른 OpenSSL 라이브러리를 번들로 포함시키는 것이에요. 버전 불일치, 런타임 시 누락된 DLL, 보안 권고 후 수동 업데이트가 프로덕션 환경에서 지속적인 마찰 원인이 됐어요.
sgcWebSockets 2026.3.0부터 Indy 기반 서버 컴포넌트인 TsgcWebSocketServer와 TsgcWebSocketHTTPServer는 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을 활성화하려면 몇 가지 속성만 변경하면 돼요:
- SSL 활성화 —
SSL속성을True로 설정하세요. - IOHandler로 SChannel 선택 —
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자 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 엔드포인트에 가장 적합해요. |
중요 사항
- Windows 전용. SChannel은 Windows API예요. 크로스플랫폼 서버(Linux, macOS)에는 OpenSSL(
iohOpenSSL)을 사용하세요. - 개인 키 필요. 서버 인증서에는 개인 키가 포함되어 있어야 해요. Windows 인증서 저장소 방법을 사용할 때 인증서는 개인 키와 함께 가져와야 해요.
- PFX 형식만 허용. SChannel은 PFX(.pfx / .p12) 인증서 파일을 허용해요. PEM 파일이 있다면
openssl pkcs12명령어를 사용해 먼저 PFX로 변환하세요. - 서비스에는 로컬 머신 저장소 사용. 프로덕션 서버에는
scspStoreLocalMachine을 사용해 사용자 계정에 관계없이 인증서에 접근할 수 있도록 하세요. - 에디션 지원. 서버 측 SChannel은 sgcWebSockets의 Professional, Enterprise, All-Access 에디션에서 사용 가능해요.
