Protokół TLS Handshake to proces kryptograficznej negocjacji, w którym przeglądarka internetowa i serwer ustalają zasady szyfrowania przed rozpoczęciem wymiany jakichkolwiek danych. Działa on na zasadzie wymiany kluczy publicznych i weryfikacji certyfikatu cyfrowego, żeby nawiązać jedno bezpieczne połączenie symetryczne dla całej sesji. Tyle teorii. W praktyce jest to brutalna wymiana pakietów sieciowych, która potrafi zepsuć się na kilkanaście różnych sposobów, jeśli administrator pomyli konfigurację na maszynie brzegowej.
Wczoraj w nocy siedziałem nad logami z Wiresharka. Próbowaliśmy zdiagnozować, czemu ruch z aplikacji mobilnej nagle umiera na load balancerze. Okazało się, że klient rzucał przestarzałym zestawem szyfrów. Serwer po prostu odrzucał to w ułamku sekundy. Odcięcie. Jak działa protokół TLS Handshake w takich warunkach? Wyjaśnienie krok po kroku wymaga zejścia do poziomu samych bajtów krążących po kablu, bo czytanie dokumentacji RFC rzadko daje odpowiedzi na problemy z produkcji.
Jak przebiega i jak działa protokół TLS Handshake na serwerze?
Wszystko zaczyna się od klienta. Przeglądarka lub aplikacja musi uderzyć do serwera z informacją, co w ogóle potrafi obsłużyć. Ten pierwszy pakiet nazywa się ClientHello. Zawiera on listę obsługiwanych wersji protokołu. Zazwyczaj jest to dzisiaj TLS 1.3 lub starszy 1.2. Do tego dochodzi długa lista Cipher Suites. To są konkretne algorytmy kryptograficzne do szyfrowania i haszowania. Klient wysyła też ciąg losowych bajtów. Ten ciąg przyda się później do wygenerowania głównego klucza sesji.
Serwer czyta ten pakiet. Musi podjąć decyzję. Wybiera z listy klienta jeden konkretny zestaw szyfrów, który sam obsługuje. Wysyła z powrotem pakiet ServerHello. W tym momencie obie strony mają już ustalony język, w jakim będą rozmawiać. Serwer dorzuca do tego swój własny ciąg losowych bajtów. Zrobiliśmy na wdrożeniu systemu dla hurtowni na wrocławskich Krzykach aktualizację reguł zapory. Potem zawiesiło się routowanie na brzegówce, więc wprowadzono poprawkę na sztywno przed poniedziałkiem. Prawda jest zresztą absolutnie tаkа, że nikt z zarządu nie rozumiał, czemu terminale nagle odrzucają połączenia. Szukaliśmy błędu w switchach. Problemem był wygasły certyfikat pośredni w starym systemie Windows 7, którego ktoś zapomniał zaktualizować. To jest bez mała najgorsza opcja z wszystkich.
Co to jest rozszerzenie SNI w fazie początkowej?
Klienci wysyłają w ClientHello bardzo ważny dodatek. Nazywa się Server Name Indication. W skrócie SNI. Zanim to wymyślono, serwery miały ogromny problem. Wyobraź sobie maszynę, która hostuje sto różnych stron internetowych pod jednym adresem IP. Kiedy przychodził request TLS, serwer nie wiedział, o jaką domenę pyta klient. Nie wiedział więc, jaki certyfikat mu odesłać. SNI rozwiązuje ten problem. Przeglądarka wprost wpisuje nazwę domeny w pierwszym pakiecie nieszyfrowanym. Serwer czyta to i dopasowuje odpowiedni plik z kluczem.
Brak SNI to dzisiaj gwarantowany błąd połączenia w nowoczesnych środowiskach chmurowych. Systemy po prostu odrzucają ruch. Nie mają czasu zgadywać intencji klienta. Wymuszamy to na poziomie load balancera. Inaczej dostajesz po oczach błędem FATAL z warstwy sieciowej.
Kto weryfikuje certyfikat SSL podczas nawiązywania sesji?
Zaraz po ServerHello serwer wysyła swój certyfikat cyfrowy. To jest dowód tożsamości. Przeglądarka odbiera ten plik i zaczyna matematyczną analizę. Certyfikat zawiera klucz publiczny serwera. Zawiera też podpis cyfrowy wystawiony przez Urząd Certyfikacji. Klienci mają w systemie operacyjnym wbudowaną bazę zaufanych urzędów. Windows ma swoją. macOS ma swoją. Firefox nosi własną listę w plikach przeglądarki.
Przeglądarka bierze ten podpis i sprawdza go matematycznie. Jeśli matematyka się zgadza, klient wie, że rozmawia z prawowitym właścicielem domeny. Jeśli w łańcuchu brakuje certyfikatu pośredniego, przeglądarka wywala czerwony ekran błędu. Użytkownik widzi ostrzeżenie o niebezpiecznym połączeniu. Zazwyczaj ucieka ze strony. Zmieniliśmy te zasady na robocie. Teraz skrypty automatycznie sprawdzają ciągłość łańcuchów co noc. Brak ciągłości oznacza natychmiastowy alert na Slacka dyżurnego admina.
Skąd przeglądarka wie, że serwer nie kłamie?
To kwestia zaufania do zewnętrznych podmiotów. Urząd Certyfikacji gwarantuje tożsamość. Ale certyfikaty mogą zostać skradzione. Dlatego wymyślono mechanizmy unieważniania. Kiedyś używano list CRL. To były gigantyczne pliki tekstowe pobierane przez przeglądarki. Ważyły za dużo. Dzisiaj używamy protokołu OCSP. Przeglądarka wysyła szybkie zapytanie do urzędu w locie. Pyta, czy dany numer seryjny jest nadal ważny. Jeśli odpowiedź brzmi nie, połączenie zostaje ubite na miejscu.
Zdarza się, że serwery OCSP mają awarię. Wtedy przeglądarka musi podjąć decyzję. Zazwyczaj stosuje zasady „Soft Fail”. Przepuszcza ruch pomimo braku odpowiedzi. To dziura w bezpieczeństwie. Mimo to biznes wymaga, żeby strony działały. Nikt nie zaryzykuje blokady sklepu internetowego z powodu awarii serwera urzędu na drugim końcu świata.
Wymiana kluczy kryptograficznych. Wyjaśnienie krok po kroku
Szyfrowanie asymetryczne jest za wolne na przesyłanie dużych plików. Zżera procesor. Dlatego używamy go tylko przez ułamek sekundy. Służy wyłącznie do bezpiecznego przekazania materiału na klucz symetryczny. Klucz symetryczny to ten sam ciąg znaków po obu stronach. Szyfruje i deszyfruje dane bardzo tanio z punktu widzenia zasobów sprzętowych.
W starych wersjach protokołu klient brał losowy ciąg bajtów, szyfrował go kluczem publicznym serwera i wysyłał. Serwer to deszyfrował swoim kluczem prywatnym. To miało gigantyczną wadę. Jeśli ktoś nagrywał ruch sieciowy przez lata, a potem ukradł klucz prywatny serwera, mógł odszyfrować całą historię. Wszystkie pakiety wstecz. To kompletna katastrofa dla bezpieczeństwa danych.
Dlatego wprowadzono mechanizm Perfect Forward Secrecy. Zamiast wysyłać gotowy klucz, obie strony używają algorytmu Diffie-Hellmana. Wymieniają się matematycznymi parametrami. Klient wysyła swoją część obliczeń. Serwer wysyła swoją. Obie strony mnożą to u siebie lokalnie. Wychodzi im dokładnie ten sam wynik. Ten wynik staje się kluczem sesji. Nawet jeśli ktoś podsłuchał wymianę parametrów, nie wyliczy z tego klucza. Z matematycznego punktu widzenia to ślepa uliczka dla atakującego.
| Cecha mechanizmu | Szyfrowanie Asymetryczne (RSA) | Wymiana Diffie-Hellman (ECDHE) |
| Zapotrzebowanie na CPU | Bardzo wysokie | Niskie przy krzywych eliptycznych |
| Ochrona wsteczna (PFS) | Brak ochrony wstecznej | Pełna izolacja sesji |
| Rola w TLS Handshake | Dawniej wymiana klucza | Obecnie standard generowania sesji |
Jak działa krzywa eliptyczna w praktyce?
Wariant ECDHE to dzisiaj standard. Zamiast ogromnych liczb pierwszych, używamy punktów na wykresie krzywej eliptycznej. Obliczenia są ułamek razy szybsze. Dają taki sam poziom bezpieczeństwa przy dużo krótszym kluczu. Przeglądarka generuje losowy punkt. Mnoży go przez parametr bazowy. Wysyła wynik do serwera. Serwer robi to samo. Na końcu obie strony uzyskują wspólny sekret. To wszystko dzieje się w milisekundach, zanim w ogóle zobaczysz ikonę kłódki na pasku adresu.
Co oznacza faza Finished i jak kończy się ten proces?
Kiedy obie strony mają już wyliczony klucz symetryczny, muszą sprawdzić, czy nikt nie zmanipulował pakietów po drodze. Klient wysyła komunikat Finished. Ten komunikat jest już zaszyfrowany nowym kluczem. Zawiera sumę kontrolną ze wszystkich poprzednich wiadomości. Serwer to odbiera. Odszyfrowuje. Sprawdza sumę kontrolną. Jeśli wszystko pasuje, serwer wysyła swój komunikat Finished. W tym momencie protokół TLS Handshake zostaje zamknięty. Rozpoczyna się normalny transfer danych aplikacji. Leci protokół HTTP.
Z perspektywy administratora to jest moment, w którym logi serwera www pokazują kod 200 OK. Zanim do tego dojdzie, warstwa sieciowa wymieniła co najmniej dwa pełne cykle zapytań tam i z powrotem. W inżynierii nazywamy to Round Trip Time. W przypadku starszych protokołów zjadało to dużo czasu. Użytkownicy na łączach mobilnych z wysokim pingiem odczuwali irytujące opóźnienia przy wchodzeniu na strony.
Dlaczego wersja 1.3 to radykalna poprawa wydajności?
Starsze systemy marnowały czas. TLS 1.2 wymagał dwóch pełnych obiegów RTT. Klient mówił cześć. Serwer odpowiadał. Klient wysyłał parametry krypto. Serwer odpowiadał. Dopiero wtedy szły dane. Wersja 1.3 ucina ten proces drastycznie. Architekci protokołu wyrzucili do kosza wszystkie stare, dziurawe algorytmy. Zostało tylko kilka najsilniejszych wariantów.
Dzięki temu klient nie musi czekać na decyzję serwera. Przeglądarka wysyła ClientHello i od razu, w tym samym pakiecie, dorzuca swoje parametry Diffie-Hellmana dla najbardziej prawdopodobnego zestawu szyfrów. Serwer to łapie. Wylicza klucz. Odpowiada gotowym ServerHello i natychmiast zamyka Handshake. Zyskujemy cały jeden obieg sieciowy. Na wolnych łączach to oszczędność rzędu kilkuset milisekund. To wprost przekłada się na wyniki w narzędziach badających szybkość ładowania domen.
Co to jest 0-RTT i czy to bezpieczne?
Wersja 1.3 wprowadziła jeszcze agresywniejszy mechanizm. Nazywa się Zero Round Trip Time. Działa przy wznawianiu sesji. Jeśli klient odwiedził serwer wczoraj, ma w pamięci bilet sesyjny. Przy kolejnej wizycie przeglądarka wysyła ClientHello i od razu wkleja do niego zaszyfrowane żądanie HTTP. Na przykład GET /index.html. Serwer odpowiada danymi bez żadnego czekania.
To ma jednak swoje wady. Pakiety 0-RTT są podatne na ataki typu Replay. Atakujący może przechwycić taki zaszyfrowany pakiet. Nie musi go wcale odszyfrowywać. Po prostu wysyła go ponownie do serwera. Jeśli to było żądanie przelewu bankowego, serwer może je wykonać dwa razy. Dlatego 0-RTT używamy wyłącznie do żądań bezpiecznych. Tаkich, które nie zmieniają stanu aplikacji na backendzie. Odczyt statycznych obrazków to dobry scenariusz. Modyfikacja bazy danych to absolutny zakaz dla tego mechanizmu.
Jak diagnozować błędy w negocjacji szyfrowania?
Kiedy protokół TLS Handshake upada, objawy bywają mylące. Użytkownik widzi błąd ERR_SSL_PROTOCOL_ERROR. To nic nie znaczy dla inżyniera. Musisz wejść głębiej. Zrzucasz ruch przez tcpdump na serwerze Linux. Otwierasz plik pcap. Szukasz pakietów oznaczonych jako Alert.
- Błąd Handshake Failure oznacza brak wspólnych szyfrów między dwiema maszynami. Masz po prostu stary sprzęt po jednej stronie kabla.
Dwa słowa diagnozy. - Błąd Certificate Expired to wina ludzi. Ktoś nie skonfigurował odnawiania w cronie.
- Błąd Unknown CA to problem z systemem klienta. Brak mu aktualnej bazy urzędów w rejestrze.
Rozwiązywanie tych awarii polega na rygorystycznym sprawdzaniu plików konfiguracyjnych. Serwery Nginx czy Apache mają dyrektywy ssl_protocols oraz ssl_ciphers. Czasami wystarczy usunąć stary ciąg znaków blokujący nowoczesne metody. Czasami trzeba wygenerować nowy plik dhparam, bo stary ma tylko 1024 bity i nowoczesne przeglądarki rzucają na to błędem z urzędu. My u siebie tniemy to skryptami w Pythonie. Skrypt testuje endpoint z zewnątrz. Symuluje dwadzieścia różnych klientów. Ostrzega nas, zanim klienci zaczną dzwonić na wsparcie.
Wpływ sprzętowej akceleracji krypto na CPU
Przetwarzanie tych wszystkich matematycznych równań kosztuje prąd. Serwery obsługujące tysiące nowych połączeń na sekundę dławią się na operacjach kryptograficznych. Dlatego stosujemy sprzętowe moduły szyfrujące. Procesory mają wbudowane instrukcje AES-NI. System operacyjny zrzuca ciężar obliczeń z głównego wątku na dedykowane obwody w krzemie. Dzięki temu load balancer może przetworzyć gigabity ruchu bez zadyszki.
Chociaż prawdę mówiąc brakuje nam twardych danych za wczoraj, więc wydaje się to tylko jedną z możliwych hipotez na najbliższy kwartał przed zmianami w architekturze. Część ruchu i tak musimy terminować na starych maszynach wirtualnych ze względów budżetowych. Odcięcie ich zabiłoby dostęp dla partnerów b2b.
Zrozumienie, jak działa protokół TLS Handshake i wyjaśnienie krok po kroku wszystkich jego faz to fundament pracy w sieciach. Szyfrowanie to nie jest magia. To ciąg ustaleń, matematycznych mnożeń i wymiany certyfikatów. Jeśli potrafisz przeczytać te pakiety w narzędziach analitycznych, żadna awaria certyfikatu cyfrowego nie zablokuje ci pracy na długo. Weź ten plik z logami sieciowymi u siebie w firmie. Przefiltruj po tcp.port == 443. Znajdź pakiet ClientHello. Przeczytaj w hexach, o co przeglądarka naprawdę prosi twój serwer. To zmieni twoje postrzeganie internetu.
Najczęściej zadawane pytania (FAQ)
-
Jak działa protokół TLS Handshake w prostych słowach?
Protokół TLS Handshake działa jak negocjacja przed rozmową. Przeglądarka i serwer witają się, ustalają wspólny język szyfrowania, sprawdzają dowód tożsamości (certyfikat) i wymieniają się jednorazowym kodem do zabezpieczenia całej sesji. -
Co to jest ClientHello w procesie szyfrowania?
To pierwszy pakiet wysyłany przez przeglądarkę do serwera. Zawiera listę obsługiwanych wersji protokołu, dostępnych algorytmów kryptograficznych oraz losowy ciąg danych potrzebny do późniejszych obliczeń matematycznych. -
Dlaczego TLS 1.3 jest szybszy od poprzednich wersji?
Wersja 1.3 ucina liczbę komunikatów wymienianych między klientem a serwerem. Zamiast dwóch cykli w tę i z powrotem (2-RTT), nawiązuje połączenie w jednym cyklu (1-RTT), wysyłając parametry klucza od razu na starcie. -
Jak serwer udowadnia swoją tożsamość przeglądarce?
Serwer przesyła swój certyfikat cyfrowy wystawiony przez zaufany Urząd Certyfikacji (CA). Przeglądarka weryfikuje podpis kryptograficzny tego dokumentu z bazą zaufanych urzędów zapisaną w systemie operacyjnym. -
Na czym polega mechanizm Perfect Forward Secrecy?
To metoda wymiany kluczy (zazwyczaj Diffie-Hellman), w której klucz sesji jest wyliczany w locie i nie jest zapisywany. Nawet po kradzieży głównego klucza prywatnego serwera, atakujący nie odszyfruje starych, nagranych wcześniej sesji. -
Co wywołuje błąd ERR_SSL_PROTOCOL_ERROR?
Błąd ten najczęściej oznacza brak zgodności algorytmów między klientem a serwerem. Występuje, gdy stara przeglądarka próbuje połączyć się z serwerem obsługującym wyłącznie nowe standardy szyfrowania.
Bibliografia
1. Naukowa i Akademicka Sieć Komputerowa – https://nask.pl
2. Związek Banków Polskich – https://zbp.pl
3. Ministerstwo Cyfryzacji – https://www.gov.pl/web/cyfryzacja
4. Urząd Komunikacji Elektronicznej – https://uke.gov.pl
