Delphi 애플리케이션에서 OpenSSL DLL을 제거하는 일은 예전에는 빌드 시점의 결정이었습니다. 컴파일러 정의를 켜고 다시 빌드해서, 자신의 컴퓨터에 OpenSSL을 둘 수 없는 고객들을 위해 별도의 실행 파일을 배포해야 했습니다. sgcWebSockets 2026.10은 이를 런타임 결정으로 바꿉니다. 시작 시 한 번 설정하는 전역 변수 하나가 애플리케이션 암호화가 OpenSSL에서 실행될지, 아니면 Object Pascal로 작성되어 라이브러리에 내장된 암호화에서 실행될지를 결정합니다.
연결 쪽, 즉 OpenSSL 없는 TLS는 OpenSSL DLL 없는 Delphi TLS 1.3에서 다룹니다. 이 글은 그 나머지, 즉 TLS 핸드셰이크 바깥에서 애플리케이션이 수행하는 서명, 해시, 키 합의, 암호화에 관한 것입니다.
시작 시 한 줄
유닛 sgcBase_Helpers는 TsgcCryptoBackend 형식의 전역 변수 sgcCryptoBackend를 선언합니다:
uses
sgcBase_Helpers;
begin
sgcCryptoBackend := cbNative;
sgcCheckNativeCrypto;
Application.Initialize;
...
이 스위치는 컴포넌트별이 아니라 전역이므로, 어떤 컴포넌트든 생성되기 전에 설정해야 합니다. sgcCheckNativeCrypto는 선택 사항입니다. 네이티브 암호화 유닛이 컴파일되어 있지 않다면, 애플리케이션이 처음 서명을 시도할 때가 아니라 시작 시점에 명확한 메시지와 함께 예외를 발생시킵니다.
세 가지 값
cbOpenSSL이 기본값입니다. 애플리케이션 암호화는 이전 버전과 정확히 동일하게 OpenSSL에서 실행되므로, 변수를 설정하기 전까지는 업그레이드해도 아무것도 바뀌지 않습니다.cbNative는 애플리케이션 암호화를 Object Pascal 구현에서 실행합니다. 이 경우 OpenSSL은 전혀 로드되지 않습니다.cbAuto는 OpenSSL 라이브러리를 로드할 수 있으면 OpenSSL을, 로드할 수 없으면 네이티브 코드를 사용합니다. 이 검사는 한 번만 실행되고 결과는 캐시됩니다.
cbAuto는 두 방식 모두로 배포되는 제품을 위한 것입니다. 일부 고객은 실행 파일 옆에 OpenSSL 라이브러리를 설치하고, 일부 고객은 그렇게 할 수 없는데, 동일한 빌드가 DLL 누락에 관한 지원 티켓 없이 양쪽 모두에서 동작합니다.
// same executable, with or without the OpenSSL libraries beside it
sgcCryptoBackend := cbAuto;
스위치의 적용 범위
이 스위치는 컴포넌트가 여러분을 대신해 수행하는 암호화 작업을 포괄합니다:
- 해시와 HMAC 헬퍼;
- JWT 서명과 검증, HS, RS, ES;
- OAuth2와 DPoP 증명;
- AWS Signature V4와 CloudFront 서명된 URL;
- Web Push;
- 종단 간 암호화(E2EE), 서로 다른 백엔드를 쓰는 피어끼리도 상호 운용되므로,
cbNative를 쓰는 클라이언트가 여전히 OpenSSL을 쓰는 서버와 통신할 수 있습니다; - WebAuthn과 패스키;
- SAML과 XML 서명;
- NTLM;
- AEAD, ML-KEM, HKDF;
- QUIC 패킷 보호, DTLS와 WebRTC 인증서, SRTP.
이 중 어느 것도 코드 변경이 필요하지 않습니다. 어제 OpenSSL로 서명되던 JWT가 오늘은 변수 설정에 따라 네이티브로 서명됩니다.
연결은 별도의 설정입니다
sgcCryptoBackend는 컴포넌트가 연결하는 방식을 바꾸지 않습니다. 연결의 TLS는 컴포넌트별로 선택되며, TCP, HTTP, WebSocket 컴포넌트와 그 위에 만들어진 MQTT 같은 모든 것, QUIC와 HTTP/3에서는 IOHandler = iohNativeTLS로, WebRTC에서는 DTLSOptions로 선택합니다:
sgcCryptoBackend := cbNative; // application crypto
oClient.TLSOptions.IOHandler := iohNativeTLS; // this connection
OpenSSL 핸들러를 그대로 유지하는 컴포넌트는 연결할 때 여전히 OpenSSL을 로드합니다. QUIC, HTTP/3, DTLS에서 iohNativeTLS를 사용하면 스위치 설정과 무관하게 OpenSSL이 전혀 사용되지 않습니다. 어디에서도 OpenSSL을 쓰지 않으려는 애플리케이션은 두 가지를 모두 설정해야 합니다. 암호화를 위한 스위치와, 보안 연결을 여는 각 컴포넌트의 핸들러입니다.
정의는 이제 선택 사항입니다
지금까지는 OpenSSL 없이 실행하려면 SGC_NATIVE_CRYPTO 컴파일러 정의가 필요했습니다. 이제는 더 이상 필요하지 않습니다. 이 정의가 없어도 OpenSSL 코드와 네이티브 코드가 모두 컴파일되며, 변수가 런타임에 어느 쪽을 쓸지 결정합니다.
이 정의는 여전히 한 가지 용도가 있습니다. sgcCryptoBackend의 설정과 무관하게 네이티브 백엔드를 강제하고, 애플리케이션 암호화 유닛에서 OpenSSL 코드를 제거하여 실행 파일을 더 작게 만듭니다. 어떤 빌드가 OpenSSL을 절대 사용하지 않을 것을 안다면, 이 정의는 여전히 올바른 선택입니다. 아직 확신이 없다면, 이 정의는 꺼둔 채로 시작 시점에 결정하십시오.
중요한 이유
- 빌드 하나로. 라이선스 문제, 모든 서드파티 바이너리를 묻는 보안 감사, 또는 아무도 DLL을 복사할 수 없는 잠긴 컴퓨터 때문에 OpenSSL 없이 배포해야 하는 고객도 다른 모두와 같은 실행 파일을 받습니다.
- 대체 수단.
cbAuto는 OpenSSL 라이브러리가 없을 때 첫 서명에서 실패하는 대신 애플리케이션이 계속 동작하게 합니다. - 모바일. iOS와 Android에서는 애플리케이션 암호화를 위해 번들로 넣을 OpenSSL 자체가 없습니다.
- 어디서나 같은 코드. 이 스위치는 Windows, Linux, macOS, iOS, Android에서 Delphi 7부터 Delphi 13, 그리고 C++Builder까지 동일하게 동작합니다.
업그레이드
cbOpenSSL이 기본값이므로 변수를 설정하기 전까지는 아무것도 바뀌지 않습니다. 네이티브 백엔드를 시험해 보려면, 위의 두 줄을 프로젝트 파일에 추가하고 테스트를 실행한 뒤 비교해 보십시오. 스위치가 적용되는 전체 범위와, 런타임에 OpenSSL을 완전히 배제하기 위해 각 영역에 필요한 설정은 도움말 항목 Running without OpenSSL에 있습니다.
다음 읽을거리
질문, 피드백, 마이그레이션 도움이 필요하신가요? 문의하기. 코드를 작성한 사람들에게서 직접 답변을 받으실 수 있습니다.
