Audyt bezpieczeństwa (autor: Jean Philippe Aumasson)
12 stycznia 2020

Chcielibyśmy ogłosić, że Ergo pomyślnie przeszedł audyt bezpieczeństwa niektórych (najbardziej krytycznych) części kodu. Tym razem audyt został przeprowadzony przez Jean-Philippe Aumasson (aka veorq, https://aumasson.jp/ ).
Szczegółowy raport znajduje się poniżej. Nie znaleziono nic krytycznego. Uwagi dotyczące znalezionych problemów:
- W przypadku hasła portfela, w następnych wersjach klienta protokołu przedstawimy rekomendację. Nie jesteśmy pewni, czy twarde egzekwowanie hasła będzie miało miejsce, ale przeprowadzimy więcej konsultacji w tej sprawie.
- Zmiana parametrów "n" i "k" ma sens tylko przy uruchamianiu nowej sieci. Zmiana tych parametrów w węźle górniczym spowoduje, że produkowane bloki będą nieważne dla innych węzłów. Zmiana tych parametrów w kliencie protokołu oznacza przejście na inny fork (bloki pochodzące od uczciwych uczestników protokołu będą odrzucane). Dlatego może nie ma potrzeby dodatkowych kontroli, ponieważ osoby uruchamiające nowe sieci ustawią "n" i "k" prawidłowo.
- Obecnie węzeł Ergo (jak również inne klientów protokołów blockchain i portfeli, o których wiemy, a także biblioteki kryptograficzne, których używamy) nie zapewniają ochrony przed atakami bocznymi działającymi lokalnie (np. ataki czasowe lub inspekcja pamięci przez złośliwe oprogramowanie lub wirusy). Proszę więc chronić maszyny, na których uruchamiacie portfele!
==========================================================================================================
% Ocena bezpieczeństwa Ergo % Jean-Philippe Aumasson % 07/Dec/19
Podsumowanie
Zostaliśmy poproszeni przez Ergo o przeprowadzenie oceny bezpieczeństwa kilku komponentów ich platformy Ergo:
- Tworzenie i weryfikacja dowodów protokołu Sigma
- Bezpieczne przechowywanie sekretów w portfelu
- Walidacja Proof-of-Work
Niniejszy krótki raport podsumowuje naszą ocenę i opisuje nasze ustalenia oraz zalecenia dotyczące łagodzenia ryzyka.
Dowody protokołu Sigma
Protokół Ergo opiera się na ErgoScript, języku skryptowym wspierającym stwierdzenia sigma, które mogą być udowodnione i zweryfikowane za pomocą nieinteraktywnych dowodów wiedzy.
Te dowody są stwierdzeniami opisanymi jako drzewo warunków AND, OR i progowych, których liście są dowodami wiedzy o problemie logarytmu dyskretnego.
Dowód stwierdzenia sigma jest następnie czyniony nieinteraktywnym dzięki transformacji Fiat-Shamir.
Ta logika jest określona w dokumencie ErgoScript, a konkretne
ruty dowodzenia i weryfikacji opisane są w jego Załączniku A.
Wyzwania implementacyjne polegają na:
- Zdefiniowaniu kodowania dowodów, które są bezpieczne i wydajne, oraz wdrożeniu serializacji i deserializacji, które zawsze udaje się w przetwarzaniu prawidłowego wejścia, a które zawsze elegancko kończy się niepowodzeniem w przetwarzaniu nieprawidłowego wejścia.
- Poprawnym wdrożeniu funkcjonalności dowodzenia i weryfikacji, zgodnie ze specyfikacją, a co najważniejsze, tak, aby żadne nieprawidłowe stwierdzenie nie mogło pomyślnie przejść weryfikacji.
Przejrzeliśmy te dwa aspekty, opierając się na kodzie w repozytorium sigmastate-interpreter oraz na dokumencie ErgoScript, starannie porównując zamierzony zachowanie (w Załączniku A) z rzeczywistym zachowaniem, jak zostało zaimplementowane.
Szczególnie przeglądaliśmy kod z SigSerializer, Interpreter oraz ProverInterpreter cech i obiektów.
Głównie szukaliśmy błędów z następujących klas:
- Niebezpieczne przetwarzanie źle sformułowanego wejścia
- Niebezpieczne przetwarzanie niezwykle długiego lub krótkiego wejścia
- Zachowanie przy dużej głębokości drzewa lub poziomie rekurencji
- Niebezpieczne użycie typów i struktur Scala
- Nieodpowiednie typy zmiennych
- Przepełnienia całkowite
- Warunki wyścigu
- Błędy logiczne
Pomimo szerokiego przeglądu, nie zidentyfikowaliśmy żadnych problemów z bezpieczeństwem.
Logika i wnętrze protokołu są jednak stosunkowo złożone, a najwyższe ryzyko widzimy w analizie i weryfikacji dowodów. Aby wykorzystać takie problemy, jednak, atakujący musiałby stworzyć semantycznie poprawny skrypt, który w jakiś sposób przynosiłby mu korzyści, a jednocześnie przechodziłby weryfikację, gdy nie powinien.
Jeśli chodzi o bezpieczeństwo oprogramowania, Scala eliminuje pewne klasy błędów, ale kod Scala może nadal cierpieć z powodu błędów z powodu specyficznego zachowania Scala lub nieobsługiwanych błędów.
Portfel
Funkcjonalność portfela Ergo umożliwia użytkownikom przechowywanie sekretu na dysku i jego odzyskiwanie, inicjując portfel nowym seedem przy pierwszym użyciu.
Ta logika jest głównie zdefiniowana w ErgoWalletActor, a kluczowym komponentem dotyczącym przechowywania sekretów jest JsonSecretStorage.
Za pierwszym razem, gdy portfel jest tworzony, polecenie InitWallet wykonuje następujące czynności:
- Generuje
settings.walletSettings.seedStrengthBitslosowych bitów, jako początkową entropię. Domyślnie generowane jest 160 bitów. - Generuje BIP39 z wygenerowanych losowych bitów, który można traktować jako kodowanie bitów entropii. Używana jest standardowa logika BIP39, z opcjonalnym hasłem.
- Wyprowadza seed z mnemoniki, używając logiki pochodzenia opartej na PBKDF2 BIP39.
- Szyfruje ten seed na dysku za pomocą AES-GCM, używając losowego nonce, oraz klucza wyprowadzonego z hasła przy użyciu PBKDF2-HMAC-SHA256 z 128000 iteracjami, używając losowej soli.
Aby odblokować już utworzony portfel, użytkownik podaje hasło, a portfel próbuje odszyfrować przechowywane dane.
Aby przywrócić istniejące konto z frazy BIP39, przeprowadzany jest podobny proces jak przy inicjalizacji, z tą różnicą, że portfel wyprowadzi seed z mnemoniki zamiast wybierać losową mnemonikę.
Dwa ryzyka, które zidentyfikowaliśmy tutaj, to:
- Brak kontroli długości hasła: ponieważ hasło jest wystarczające do uzyskania dostępu do seeda, biorąc pod uwagę sekret przechowywany na dysku portfela, hasło powinno w teorii mieć co najmniej tyle entropii, co mnemonika, a w praktyce powinno być praktycznie trudne do złamania. Dlatego zalecamy egzekwowanie minimalnej długości hasła, na przykład 16 znaków.
- Kopie wartości sekretów (hasło, seed i wyprowadzone klucze prywatne) mogą pozostać w pamięci po wykonaniu oprogramowania portfela, co jest wewnętrzną ograniczeniem języków z garbage collection, takich jak Scala.
Inny proces lub użytkownik dzielący tę samą przestrzeń adresową pamięci mógłby potencjalnie odzyskać sekrety, a także mogłyby one pojawić się w zrzutach awaryjnych. Na najlepszą naszą wiedzę, nie ma skutecznego łagodzenia w czystej Scali.
Walidacja PoW
Po wcześniejszym przeglądzie bezpieczeństwa Autolykos PoW, przeprowadziliśmy kolejny przegląd, koncentrując się na jego najnowszej logice weryfikacji, a w szczególności na zmianach w commicie eb0f85a.
Głównym istotnym plikiem jest AutolykosPowScheme, a inne ważne operacje są na przykład zaimplementowane w
HeadersProcessor oraz ModifierValidator.
Sprawdziliśmy, że zaimplementowana logika weryfikacji jest zgodna z tą określoną w specyfikacjach Autolykos i że jest prawidłowo zintegrowana w logice walidacji nagłówków bloków.
Uważamy, że następujące punkty powinny zostać rozwiązane:
- Surowsza walidacja
kin: chociaż klasa egzekwujek<=32(liczba elementów w rozwiązaniu) in<31(log2 całkowitej liczby elementów), słabe mogłyby nadal być tworzone z dozwolonych parametrów. Funkcjavalidate()może zatem mieć dodatkową walidację, żeniksą równe zamierzonym
wartościom. - Upewnij się, że
kinsą wartościami dodatnimi, ponieważ obecnie ujemne (jakoInts) przechodziłyby przez instrukcjeassert.
Share post
13 sierpnia 2025
12 maja 2025






