Blockchain. Generowanie klucza publicznego i prywatnego

Blockchain. Generowanie klucza publicznego i prywatnego
J1
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 2 lata
  • Postów:224
0

Piszę sobie blockchaina w Java. Nie jestem specjalistą od blockchaina i mam takie pytanko. Każdy portfel ma swój klucz publiczny i klucz prywatny, przez który ma się dostęp. Oprogramowałem już generowanie bloków, nadawanie im hashów, wykonywanie transakcji, które mają również hashe i przesyłanie krypto poprzez te transakcje, które umieszczam w blokach. Jednak do tej pory ustawiałem na sztywno klucz publiczny, jakiś byle jaki ciąg znaków, żeby te transakcje miały nadawcę i odbiorcę. Teraz chciałbym napisać już algorytm do generowania klucza publicznego i prywatnego. Nie wiem czy te dwa klucze muszę być generowanie z siebie, czy nie mają nic wspólnego lub jaki algorytm hashowania użyć.


edytowany 2x, ostatnio: Jonki1997
szweszwe
  • Rejestracja:ponad 11 lat
  • Ostatnio:12 dni
  • Lokalizacja:Kraków
  • Postów:1694
1

Nie wiem czy te dwa klucze muszę być generowanie z siebie, czy nie mają nic wspólnego lub jaki algorytm hashowania użyć.

No muszą być z siebie bo to jest para kluczy. O to właśnie w tym wszystkim chodzi, że publiczny możesz udostępnić każdemu i ktoś zaszyfruje nim jakąś wiadomość, ale odczyta ją tylko posiadacz klucza prywatnego.

Nie wiem jaki algorytm bo się nie znam na kryptografii ale możesz zobaczyć jak to jest zrobione w innych projektach. W Bitcoinie na pewno była używana arytmetyka krzywych eliptycznych. O takie coś: https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm

Do poczytania jeszcze fajna książka o Bitcoinie właśnie. Tutaj rozdział "Keys, Addresses" gdzie wszystko jest opisane:
https://github.com/bitcoinbook/bitcoinbook/blob/develop/ch04.asciidoc

edytowany 1x, ostatnio: szweszwe
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:12 dni
  • Postów:3277
2

Zależy jakiego algorytmu szyfrowania użyjesz. Dla krzywych eliptycznych możliwe jest wygenerowanie klucza publicznego z klucza prywatnego. Dla RSA nie da się wykonać takiej operacji.
Algorytm hashowania to osobna kwestia od samego podpisu / szyfrowania. Dla potwierdzenia, że jakaś porcja danych jest "podpisana" nie potrzebowałbyś jej hasha, bo można ją podpisać w całości (np. szyfrując kluczem prywatnym RSA), ale wtedy podpis zajmowałby ~tyle co dane, w dodatku asymetryczne metody szyfrowania są wolne. Dlatego stosuje się skrócenie danych do sygnatury (np. SHA256), otrzymujesz 8 bajtów, które podpisujesz. i w efekcie dostajesz podobnej długości sygnaturę.

Użycie funkcji hash jest okupione wystawieniem się na atak na tę część podpisu, bo skoro masz np. 10kB lub więcej danych, a skróty tych danych to jedynie 8 bajtów, to istnieje nieskończona liczba różnych danych, które dadzą ten sam wynik funkcji hashującej. Atakujący może więc przygotować porcję danych, którą chce podpisać, następnie zmieniać nieistotne z jego punktu widzenia jej części, tak długo jak uzyska taki sam hash jak w oryginalnym wpisie. Obchodzi się to poprzez zwielokrotnienie liczby rund hashujących. Czyli tworzysz sobie ciąg n = hash(n-1) i im on jest dłuższy, tym dłużej potrwa wykonanie skutecznego ataku przy założeniu użycia takiej samej mocy obliczeniowej.

Z praktycznej strony - użytkownik jest w stanie przechowywać w głowie jedynie hasło. W przypadku krzywych eliptycznych (ECC) można na podstawie tego hasła wygenerować klucz prywatny a z niego klucz publiczny, nie ma więc potrzeby bezpiecznego przechowywania czegokolwiek innego niż właśnie hasło.
W przypadku RSA potrzebujesz znaleźć 2 duże liczby pierwsze (nie do zapamiętania) na ich podstawie wygenerować klucz prywatny i klucz publiczny (też nie do zapamiętania), klucz prywatny musisz trzymać w bezpiecznym miejscu (np. w formie zaszyfrowanej na dysku). Do podpisania danych w przypadku ECC potrzebujesz jedynie użytkownika, który nie zapomniał hasła, do podpisu opartego na RSA potrzebujesz już danych, które musisz "gdzieś" przechowywać. W Java masz gotowe do użycia algorytmy szyfrujące oparte zarówno o RSA, jak i ECC.

Disclajmer - moja wiedza o kryptografii jest dość pobieżna, a i to, głównie od praktycznej strony. Jeżeli napisałem tu jakieś kompletne głupoty, to będę wdzięczny za ich wytknięcie, a gdyby ktoś faktycznie chciał zrobić "coś", gdzie bezpieczeństwo ma znaczenie, to polecam poszukać i skonsultować swój pomysł z jakimiś specjalistami konkretnie w tej dziedzinie. O ile można sobie skorzystać z gotowych algorytmów dostępnych w bibliotekach, to już łączenie ich w jakiś spójny system potrafi wygenerować sporo luk.

PI
Wow, ale mądrze brzmi ten post
piotrpo
@Pinek: Trzeba pracować przynajmniej nad pozorami...
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

@piotrpo:

Dla RSA nie da się wykonać takiej operacji.

:press_x_to_doubt:

  1. W praktyce używa się e=3 albo e=65537 więc w 99% przypadków da się wygenerować klucz publiczny z prywatnego biorąc sobie n.
  2. Nawet jeśli użyje się innego e to zwykle jest bardzo małe więc można by je policzyć za pomocą ataku Wienera.
  3. Co prawda sam klucz prywatny to d,n ale większość formatów przechowywania klucza ma tam też p i q (a dla formatu RSA-CRT jeszcze dp, dq i qinv), a mając p i q można sobie policzyć e = modinv(phi(n)) bez problemu.

Niemniej faktycznie w przypadku ogólnym, mając tylko modulus i jedną z eksponent nie da się wyliczyć drugiej eksponenty.

bo można ją podpisać w całości (np. szyfrując kluczem prywatnym RSA), ale wtedy podpis zajmowałby ~tyle co dane, w dodatku asymetryczne metody szyfrowania są wolne

Nie, nie mógłbyś, bo RSA co do zasady pozwala pracować z danymi mniejszymi niż n. Wiec to nie problem rozmiaru podpisu, co problem rozmiaru klucza.

@Jonki1997: nie do końca rozumiem co chcesz zrobić tutaj. Chcesz napisać sobie obsługę jakiegoś istniejącego blockchaina czy napisać od zera własny?


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 3x, ostatnio: Shalom
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:12 dni
  • Postów:3277
0

@Shalom: Pierwsze uwaga ok, druga - każdy (współczesny) szyfr ma jakiś maksymalny rozmiar obsługiwanego bloku danych. Co stoi na przeszkodzie podzielić sobie dane na części i każdą z nich zaszyfrować w ten sam sposób RSA? Piszę czysto teoretycznie, bo o potencjalnym osłabieniu bezpieczeństwa przez występowanie tożsamych zaszyfrowanych bloków wiem, jak również zgadzam się, że nie ma możliwości wykorzystania mechanizmów typowych dla symetrycznych szyfrów blokowych (typu CBC, czy CTR)?

Shalom
każdy (współczesny) szyfr ma jakiś maksymalny rozmiar obsługiwanego bloku danych tylko że dla szyfrów symetrycznych mówimy tu o terabajtach danych ;) Sam sobie odpowiedziałeś - chunkowanie i szyfrowanie osobnych kawałków to nic innego jak ECB.
piotrpo
No nie, bloki stosowane w takim AES to 128b trochę daleko od "terabajtów"
Shalom
Ja mówie o tym ile danych można zaszyfrować jednym kluczem bez problemów.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.