Jaki jest najbezpieczniejszy sposób zaszyfrowania 4 bajtów na mniej niż 40 bajtów przez jedną stronę, które będą publicznie dostępne?

Nov 19 2020

Mam projekt, w którym użytkownik musi przechowywać kod U32 zaszyfrowany w łańcuchu blokowym, tak aby mógł go samodzielnie odzyskać: użytkownik zawsze będzie miał dostępny klucz, ale może „zapomnieć” o wartości U32. Żadna inna strona nie musi dekodować informacji, ale ostatecznie tekst jawny będzie również dostępny w łańcuchu.

Użytkownik ma ziarno entropii, z którego można deterministycznie wyprowadzić nieskończoną liczbę kluczy o dowolnej wielkości. Chciałem użyć pojedynczego bloku AES, ale przyszło mi do głowy, że wystarczy prosty XOR. Zakładając, że użytkownik uzyskuje unikalny „klucz” za każdym razem, gdy wykonuje tego typu operację, czy jest jakiś powód, aby robić coś bardziej skomplikowanego?

Odpowiedzi

3 ModalNest Nov 19 2020 at 22:56

Oczywistą odpowiedzią jest użycie jednorazowej tablicy czasowej . Jeśli naprawdę używasz unikalnego losowego 4-bajtowego klucza dla każdego 4-bajtowego bloku, to jest to bezpieczne.

Użytkownik ma ziarno entropii, z którego można deterministycznie wyprowadzić nieskończoną liczbę kluczy o dowolnej wielkości.

Prawdziwym problemem jest ta „pochodna” losowość i to, jak bardzo jest ona losowa. Nie znam żadnego nieskończonego źródła tego.

Dzięki Salsa / ChaCha można wygenerować do 2 ^ 64 512-bitowych kluczy, z których każdy może zaszyfrować 16 różnych 4-bajtowych bloków. Więc przypuszczam, że jest wystarczająco nieskończony.

Użytkownicy musieliby zasiać go 320-bitowym kluczem. Muszą zmienić swój klucz po 2 ^ 68 (jeśli moja matematyka się nie myli) szyfrowaniu. Użycie konfiguracji podobnej do XChaCha umożliwia rozszerzenie tego do 2 ^ 132.

Podsumowując, jeśli masz kryptograficznie bezpieczne źródło losowości, możesz po prostu XOR.

2 SEJPM Nov 19 2020 at 23:00

Tak więc standardowym rozwiązaniem kryptografa z tymi ograniczeniami byłoby użycie AES-128-GCM z 12-bajtową wartością numeryczną i 16-bajtowym znacznikiem uwierzytelniającym przy użyciu stałego tajnego klucza.

Jednak fakt, że ta wartość jest przechowywana w łańcuchu bloków, pozwala na pewne niepotrzebne redukcje rozmiaru:

  1. Wartość jednorazową można porzucić i zamiast tego ponownie wyprowadzić z liczby wartości zapisanych w łańcuchu bloków - co można odzyskać, sprawdzając poprzedni stan łańcucha. Zakłada się, że klucz jest używany tylko dla tej aplikacji i żadne inne użycie klucza nie może przypadkowo użyć tej samej pary klucz / numer jednorazowy, co każda transakcja.
  2. Tag uwierzytelniający można usunąć, ponieważ zawsze wiesz, jaki jest szyfrogram i nie można go zmienić po przesłaniu dzięki podpisowi na transakcji i niezmienności łańcucha bloków. Zauważ, że zakłada się, że po pobraniu wartości ufasz klientowi łańcucha bloków, że nie dostarczy niewłaściwej wartości, albo że możesz w jakiś sposób również pobrać odpowiednią podpisaną transakcję i ją zweryfikować.

Teraz, jeśli usuniesz oba z nich, zasadniczo pozostaniesz z AES-128-CTR, który oblicza $\operatorname{AES}_K(C)\oplus M$ na klucz stały $K$ i wartość licznika $C$ i wiadomość $M$. Zauważ, że nie powoduje to żadnego rozszerzenia wiadomości, ponieważ możesz po prostu odtworzyć tę samą część wyjścia AES do odszyfrowania.