Usunięcie DLL-i OpenSSL z aplikacji Delphi było kiedyś decyzją podejmowaną podczas budowania. Włączałeś define kompilatora, przebudowywałeś projekt i wysyłałeś drugi plik wykonywalny klientom, którzy nie mogli mieć OpenSSL na swoich maszynach. sgcWebSockets 2026.10 zamienia to w decyzję podejmowaną w czasie działania: jedna globalna zmienna, ustawiona raz przy starcie, decyduje, czy kryptografia aplikacji działa na OpenSSL, czy na kryptografii wbudowanej w bibliotekę, napisanej w Object Pascal.
Strona połączeniowa, czyli TLS bez OpenSSL, jest opisana w Delphi TLS 1.3 bez DLL-i OpenSSL. Ten wpis dotyczy wszystkiego innego: podpisów, skrótów, uzgadniania kluczy i szyfrowania, które Twoja aplikacja wykonuje poza handshake'iem TLS.
Jedna linia przy starcie
Jednostka sgcBase_Helpers deklaruje globalną zmienną sgcCryptoBackend, typu TsgcCryptoBackend:
uses
sgcBase_Helpers;
begin
sgcCryptoBackend := cbNative;
sgcCheckNativeCrypto;
Application.Initialize;
...
Przełącznik jest globalny, a nie ustawiany per komponent, więc ustaw go, zanim powstanie jakikolwiek komponent. sgcCheckNativeCrypto jest opcjonalne: jeśli jednostki natywnej kryptografii nie zostały wkompilowane, zgłasza błąd przy starcie z czytelnym komunikatem, zamiast dopiero przy pierwszym podpisie, jaki próbuje wykonać Twoja aplikacja.
Trzy wartości
cbOpenSSLto wartość domyślna. Kryptografia aplikacji działa na OpenSSL, dokładnie jak w poprzednich wersjach, więc aktualizacja niczego nie zmienia, dopóki nie ustawisz zmiennej.cbNativeuruchamia kryptografię aplikacji na implementacji w Object Pascal. OpenSSL nigdy nie jest dla niej ładowany.cbAutoużywa OpenSSL, gdy jego biblioteki da się załadować, a kodu natywnego, gdy się nie da. Sprawdzenie odbywa się raz, a wynik jest zapamiętywany.
cbAuto jest właściwym wyborem dla produktów wdrażanych na oba sposoby. Część klientów instaluje biblioteki OpenSSL obok pliku wykonywalnego, część nie ma na to pozwolenia, a ten sam build działa dla obu grup, bez zgłoszenia do supportu o brakującej DLL.
// same executable, with or without the OpenSSL libraries beside it
sgcCryptoBackend := cbAuto;
Co obejmuje przełącznik
Przełącznik obejmuje kryptografię, którą komponenty wykonują w Twoim imieniu:
- funkcje pomocnicze do haszowania i HMAC;
- podpisywanie i weryfikację JWT, HS, RS i ES;
- dowody OAuth2 i DPoP;
- AWS Signature V4 i podpisane URL-e CloudFront;
- Web Push;
- szyfrowanie end-to-end (E2EE), gdzie strony na różnych backendach współpracują ze sobą, więc klient na
cbNativerozmawia z serwerem wciąż działającym na OpenSSL; - WebAuthn i passkeys;
- SAML i podpisy XML;
- NTLM;
- AEAD, ML-KEM i HKDF;
- ochronę pakietów QUIC, certyfikaty DTLS i WebRTC oraz SRTP.
Żadne z nich nie wymaga zmiany kodu. JWT, który wczoraj był podpisywany za pomocą OpenSSL, dziś jest podpisywany natywnie, bo tak mówi zmienna.
Połączenia to osobne ustawienie
sgcCryptoBackend nie zmienia sposobu, w jaki komponent się łączy. TLS połączenia jest wybierany per komponent, za pomocą IOHandler = iohNativeTLS, na komponentach TCP, HTTP i WebSocket oraz wszystkim, co jest na nich zbudowane, takim jak MQTT, na QUIC i HTTP/3, oraz przez DTLSOptions dla WebRTC:
sgcCryptoBackend := cbNative; // application crypto
oClient.TLSOptions.IOHandler := iohNativeTLS; // this connection
Komponent, który zachowuje handler OpenSSL, nadal ładuje OpenSSL przy łączeniu się. Przy iohNativeTLS na QUIC, HTTP/3 i DTLS OpenSSL nie jest używany w ogóle, niezależnie od tego, co mówi przełącznik. Aplikacja, która nie chce OpenSSL nigdzie, ustawia obie rzeczy: przełącznik dla swojej kryptografii oraz handler na każdym komponencie, który otwiera bezpieczne połączenie.
Define jest teraz opcjonalny
Do tej pory działanie bez OpenSSL oznaczało define kompilatora SGC_NATIVE_CRYPTO. Nie jest on już potrzebny. Bez niego wkompilowany jest zarówno kod OpenSSL, jak i kod natywny, a to zmienna decyduje w czasie działania.
Define wciąż ma jedno zastosowanie. Wymusza backend natywny niezależnie od tego, co mówi sgcCryptoBackend, i usuwa kod OpenSSL z jednostek kryptografii aplikacji, dzięki czemu plik wykonywalny jest mniejszy. Jeśli wiesz, że dany build nigdy nie użyje OpenSSL, wciąż jest to właściwy wybór. Jeśli jeszcze nie wiesz, zostaw go wyłączonym i zdecyduj przy starcie.
Dlaczego to ma znaczenie
- Jeden build. Klienci, którzy muszą dostarczać oprogramowanie bez OpenSSL, z powodu licencjonowania, audytu bezpieczeństwa pytającego o każdy plik binarny firm trzecich, albo zablokowanych maszyn, na które nikomu nie wolno kopiować DLL, dostają ten sam plik wykonywalny co wszyscy inni.
- Fallback.
cbAutoutrzymuje działanie aplikacji, gdy brakuje bibliotek OpenSSL, zamiast zawieść przy pierwszym podpisie. - Mobile. Na iOS i Androidzie nie ma OpenSSL do dołączenia dla kryptografii aplikacji.
- Ten sam kod wszędzie. Przełącznik działa tak samo na Windows, Linuksie, macOS, iOS i Androidzie, z Delphi od 7 do 13 oraz z C++Builder.
Aktualizacja
Nic się nie zmienia, dopóki nie ustawisz zmiennej, ponieważ cbOpenSSL jest wartością domyślną. Aby wypróbować backend natywny, dodaj powyższe dwie linie do pliku projektu, uruchom testy i porównaj wyniki. Pełna lista tego, co obejmuje przełącznik, oraz jakie ustawienie jest potrzebne w każdym obszarze, aby w czasie działania nie było w ogóle OpenSSL, znajduje się w temacie pomocy Running without OpenSSL.
Czytaj dalej
- Delphi TLS 1.3 bez DLL-i OpenSSL, strona połączeniowa
Pytania, uwagi lub potrzebujesz pomocy przy migracji? Skontaktuj się z nami. Otrzymasz odpowiedź od osób, które napisały ten kod.
