Akademia NIS2/KSC2 od sekuraka. 19 października start drugiej edycji!

Konferencja Mega Sekurak Hacking Party w Krakowie – 26-27 października!

 

Mamy problem – czyli jak CA “generował” klucze na podstawie XKCD

21 października 2026, 20:00 | Aktualności | 1 komentarz

Czy rzut kostką jest losowy? W dużym przybliżeniu ludzkość uznała ten deterministyczny układ chaotyczny za wystarczająco nieprzewidywalny, aby wykorzystać go w różnego rodzaju grach “losowych”. Jednak na poziomie mechaniki klasycznej, ciężko upatrywać tam prawdziwej losowości. Raczej dużą czułość na warunki początkowe i błąd pomiaru. W przypadku kryptografii, jeden rzut zwykłą sześcienną kostką, to może być za mało (gdybyście zgadywali ile nam teraz wyszło, to 4 oczka), dlatego inwestujcie w lava lampy. Jedna z firm wystawiających certyfikaty miała jeden z kluczy prywatnych będący liczbą 4. Tak, 4 jak na XKCD, nie że rozpoczynające się od 4, czy mający 4 bity/bajty. Po prostu “4” (słownie: cztery). Inne też nie były wygenerowane lepiej.

 TLDR:

  • Incydent: Wykryto przejęcie kluczy prywatnych 8 pośrednich CA należących do indyjskiego dostawcy eMudhra.
  • Przyczyna: Generowanie skrajnie słabych kluczy ECDSA o drastycznie obniżonej entropii (klucz prywatny d był bardzo małą liczbą, np. d = 4).
  • Skutki: Możliwość odtworzenia klucza prywatnego w milisekundy i prowadzenia ataków Man-in-the-Middle (MitM) na dowolną domenę.
  • Reakcja: Certyfikaty są unieważniane i blokowane po SPKI przez przeglądarki oraz systemy operacyjne; wymagana jest aktualizacja trust store.


Gdy klient HTTP łączy się z serwerem zabezpieczającym komunikację przy pomocy TLS, zostaje mu przedstawiony certyfikat czyli dokument wiążący nazwę domeny z kluczem publicznym serwera. Generalnie przyjmuje się, że bardzo dobrze by było, gdyby tylko właściciel serwera oraz domeny, która na niego pokazuje mógł mieć taki certyfikat. W innym przypadku podszywanie się pod dowolne domeny byłoby bardzo ułatwione (z dokładnością do cert pinningu i HSTS). Skąd więc wiadomo, że certyfikat jest poprawny i dlaczego nie generuje ostrzeżenia o tym, że mógł zostać wygenerowany przez każdego? No bo jego ważność została potwierdzona przez urząd certyfikacji (CA, Certificate Authority) – podmiot, któremu przeglądarka i system operacyjny ufają z góry. Zaufanie to ma strukturę łańcucha. Na samym jego początku (w korzeniu) znajduje się root CA, którego certyfikat (zawierający klucz publiczny, okres ważności oraz podpis komplementarnym kluczem prywatnym) jest przechowywany w zaufanym miejscu tzw. trust store. Jest to certyfikat wykorzystywany tylko do weryfikacji podpisów. Klucz prywatny jest trzymany w bezpieczny sposób (np. na HSM), offline przez urząd certyfikacji. Używa się go rzadko, tylko do podpisywania pośrednich CA i CRL (czyli listy unieważnionych certyfikatów). 

Dalej w łańcuchu zaufania znajdują się pośredniczące CA (intermediate CA) i to właśnie one na co dzień wystawiają certyfikaty końcowe, np. dla stron WWW czy wydawców oprogramowania. Klient (czyli np. przeglądarka) weryfikuje łańcuch od liścia w górę, sprawdzając podpis certyfikatu z kluczem publicznym pośredniczącego CA, podpis intermediate CA przy pomocy klucza publicznego roota, a ten ostatni jest potwierdzony w trust store. Widać zatem, jak ważną rolę pełnią główne certyfikaty – stanowią podstawę całego łańcucha zaufania. Ale klucz pośredniego CA wystarczy, żeby wystawić certyfikat na dowolną domenę – i żaden klient tego nie odróżni.

eMudhra to indyjska firma, która działa jako urząd certyfikacji (CA) i dostawca usług zaufania cyfrowego. Otrzymała licencję w 2008 roku i jest największym licencjonowanym CA w Indiach. Według internetowych źródeł wydała ponad 100 mln certyfikatów podpisu cyfrowego. W kontekście WebPKI to dużo mniejszy gracz, ale największy w Indiach. 

17 października, badacz podpisujący się jako Wayne, zgłosił do programów root (Chrome, Mozilla, eMudhra, Apple, Microsoft) przejęcie kluczy prywatnych ośmiu pośrednich CA tego dostawcy.  Jako dowód podpisał każdym z ośmiu kluczy komunikat “We have a problem here – Wayne” –  w rzeczy samej, mamy problem (i to akurat równolegle z wyciekniętą informacją o krytycznej luce dotykającej PHP, prawo Murphiego znów daje o sobie znać). Wiadomość i status naprawy można śledzić tutaj.

No i teraz najważniejsze, według Bugzilli, 30 kwietnia 2025 miała miejsce ceremonia generowania 24 par kluczy. Klucze zostały podzielone na trzy serie A, B, C, a każda seria obejmowała CA z kluczami generowanymi algorytmem RSA-4096 (większa kompatybilność) jak i ECDSA (krzywa eliptyczna P-384, szybsze podpisy, mniejsze klucze) – jeśli CA ma wystawione równolegle dwa (lub więcej) rodzaje kluczy to klienci mogą sobie wybrać ten, który spełnia ich wymagania. Klucze były przeznaczone dla pośrednich CA wystawiających certyfikaty TLS trzech typów (DV, OV, EV) oraz certyfikaty do podpisywania kodu (CS). Trzy serie × dwa algorytmy × cztery zastosowania dają 24 klucze.

Przeznaczenie serii było następujące:

  • A – generowane przez HSM Entrust na Indie
  • B – generowane przez HSM Utimaco na Europę
  • C – generowane przez HSM Utimaco na USA

Opisywanym problemem dotknięte są tylko klucze P-384 serii B i C. Klucze RSA i seria A (została zastąpiona przez A-1 w maju 2025) według obecnej wiedzy są poprawne. 

Według wstępnej analizy coś poszło nie tak i dla kluczy przeznaczonych na rynek zagraniczny do ceremonii generowania dodano test – dokonano dwóch operacji – wrap/unwrap, czyli bezpiecznego eksportu i importu klucza między sprzętowymi modułami bezpieczeństwa. Za sprawą nieustalonego jeszcze dokładnie błędu w skryptach obsługujących urządzenia HSM, doszło do wygenerowania słabszych kluczy (nazywanie liczby 4 jako “weaker” key brzmi trochę zabawnie, czy to znaczy że “stronger” był liczbą dwucyfrową?) i to one zostały przez przypadek wykorzystane do wygenerowania CSR i podpisane przez root CA. Te słabsze CSR zostały też przesłane do Sectigo do krzyżowego podpisania. 

W przypadku ECDSA na krzywej NIST P-384 klucz prywatny to po prostu skalar oznaczony jako d. Klucz publiczny to punkt Q na krzywej uzyskany przez d-krotne “dodanie” punktu bazowego G (z którego każdy korzysta). Bezpieczeństwo ECDSA opiera się na problemie logarytmu dyskretnego na krzywej eliptycznej (ECDLP). Znając G i Q nie powinno się dać wyznaczyć d. Najlepszy znany atak wymaga około √n operacji (Metoda rho Pollarda dla logarytmu dyskretnego, który wykorzystuje znany i lubiany paradoks urodzin). Poziom bezpieczeństwa określa się na 192 bity, co jest na razie daleko poza zasięgiem jakiejkolwiek mocy obliczeniowej – ale z jednym warunkiem. Skalar d musi być wylosowany z przedziału [1, n-1], gdzie n jest rzędem punktu bazowego G (dla P-384 to duża liczba na poziomie 2^384). Klucze wygenerowane przez eMudhra były w praktyce samymi zerami, poza ostatnim bajtem (d < 256). Efektywnie entropia wyniosła więc 8 bitów. Dla jednego z pośrednich CA wartość tego ostatniego bajtu wyniosła 4 (d=4). Przy takim zakresie nie trzeba żadnej analizy, ba, nie jest wymagana nawet gumowa pałka. Podkreślamy – to nie jest “hasło do certyfikatu”, atakujący nie potrzebował żadnego wycieku czy dostępu do infrastruktury CA. Do odzyskania wystarczył sam publiczny certyfikat. Nie trzeba było szukać żadnego “ataku kryptograficznego”, żadnej kryptoanalizy. Odtworzenie klucza prywatnego certyfikatu to milisekundy na najtańszym (AD 2026 przy niedoborach i kosmicznych cenach wszystkiego z powodu bańki AI) laptopie. To oczywiście nie pierwsza tego typu wpadka. Ale te poprzednie (jak np. OpenSSL z 2008 roku) nie były tak spektakularne. 

Inną rozpatrywaną hipotezą (na HN, co jest sprzeczne z dyskusją na Bugzilli oraz komunikatem CA) w kontekście przyczyn wystąpienia problemu jest wygenerowanie słabych kluczy poza HSM i ich przypadkowe zaimportowanie. W wyniku tego zdarzenia, możliwe było np. podszycie się pod dowolną stronę serwowaną po HTTPS. Chcecie api.github.com? Albo https://sekurak.pl? Proszę bardzo. Wskazano na następujące certyfikaty (dla których odzyskano klucz prywatny):

Intermediate CAPodmiotSeriaZastosowanieKlucz prywatny d
EM DV TLS CA – G3BeMudhra BV (NL)BTLS156
EM OV TLS CA – G3BeMudhra BV (NL)BTLS155
EM EV TLS CA – G3BeMudhra BV (NL)BTLS115
EM OV CS CA – G3BeMudhra BV (NL)BCode signing66
EM DV TLS CA – G3CeMudhra Inc (US)CTLS230
EM OV TLS CA – G3CeMudhra Inc (US)CTLS4
EM EV TLS CA – G3CeMudhra Inc (US)CTLS56
EM OV CS CA – G3CeMudhra Inc (US)CCode signing237

Wartości d sprawdziliśmy samodzielnie: dla d = 1…255 policzyliśmy d·G na krzywej P-384 i porównaliśmy SHA-256 z SPKI z opublikowanymi hashami. Wszystkie osiem się zgadza.

Każdy z nich istnieje w dwóch wersjach: wystawionej przez root emSign oraz jako cross-sign pod rootem Sectigo AAA Certificate Services – oba warianty mają ten sam SPKI, czyli ten sam klucz. Pełna lista odcisków SHA-256, hashy SPKI i numerów seryjnych jest w affected-certificates.json. Ten cross-sign komplikuje blokadę, bo każdy pośredniczący CA ma bliźniaka z tym samym kluczem pod rootem Sectigo. Na czas pisania tego artykułu Sectigo twierdzi, że root był usunięty z magazynów Chrome i Mozilli ale wciąż dostępny w M$ oraz Apple. Skuteczna blokada musi działać na poziomie SPKI a nie pojedynczego certyfikatu czy roota firmy eMudhra. (aktualizacja 21.10.2026 19:39 CEST – już Sectigo unieważniło cross-signy według komentarza na Bugzilli)

Jak zwykle od katastrofy było o włos, ale jednak “nic” się nie wydarzyło w kontekście bezpieczeństwa przeglądarek, czego dowodzi Certificate Transparency. Wszystkie większe przeglądarki wymagają, żeby certyfikat TLS trafił do CT. Zatem trafiłyby tam też podrobione certyfikaty. Wedle Chrome Root Program, przed blokadą w CT, nie pojawił się żaden certyfikat wystawiony przez sześć dotkniętych CA dla TLS. Pozostałe dwa CA są wykorzystywane do podpisywania kodu i w ich przypadku nie ma publicznego rejestru, czy ktoś się nie pokusił o ich wykorzystanie. Niestety nie wszystkie klienty HTTP wymuszają CT, nie robi tego curl ani inne biblioteki programistyczne. Próżno też szukać tego typu zabezpieczenia w urządzeniach IoT. 

Curl przed aktualizacją systemowego trust store.

Co robić jak żyć? Najlepiej przetestować swoje przeglądarki i wykorzystywane klienty a następnie wykonać ich aktualizację. Większość dostawców zdążyła już zablokować dotknięte pośrednie CA, przy pomocy hashy SPKI. Mozilla i Chrome usunęły cały root emSign ECC Root CA – G3, co ma to też swoje wady, część poprawnie działających certyfikatów przestanie działać do momentu podmiany certyfikatów przez administratorów. 

Lista poprawek w zależności od wersji:

OprogramowanieWersja z poprawką
Go1.27.3, 1.26.10
Python certifi2026.10.19
Rust webpki-roots / webpki-root-certs1.0.10
NSS3.131.1
Electron44.9.1, 43.8.1, 42.11.16
Homebrew ca-certificates2026-09-25_1
Node.jsw przygotowaniu
Composer ca-bundlew przygotowaniu

Nie należy zapominać o magazynach certyfikatów wewnątrz kontenerów i aplikacji z własnymi bundle. Uwadze polecamy tez użytkownikom macOS plik /etc/ssl/cert.pem.

~BLH

Edycja 21.10.2026

Chcielibyśmy zagrać z Wami w grę…

Spodobał Ci się wpis? Podziel się nim ze znajomymi:



Komentarze

  1. a

    Chciałbym to wszystko rozumieć na tym poziomie.

    Odpowiedz

Odpowiedz