Podstawa wykładowa: Część 6 - slajdy 11, 36, 41, 42, 43: konflikt pomiędzy szyfrowaniem semantycznym a deduplikacją danych, zbieżne szyfrowanie (Convergent
Encryption / Content-Hash Keying), klucz K = H(M), szyfr blokowy AES-CTR/CBC, tag weryfikacji, bezpieczeństwo w chmurze wielodzierżawnej.
Cel
Celem ćwiczenia jest rozwiązanie fundamentalnego konfliktu pomiędzy prywatnością szyfrowania a efektywnością deduplikacji w chmurze poprzez implementację zbieżnego szyfrowania
(Convergent Encryption) w Pythonie. Student implementuje schemat, w którym klucz szyfrujący jest deterministycznie wyprowadzany ze skrótu kryptograficznego zawartości bloku, co pozwala
różnym użytkownikom generować identyczne szyfrogramy dla identycznych plików bez ujawniania ich treści dostawcy chmury.
Scenariusz – opis
W erze chmury obliczeniowej dostawcy pamięci masowych masowo stosują deduplikację danych w celu obniżenia kosztów infrastruktury. Równocześnie świadomi użytkownicy i regulacje prawne (np. RODO) wymagają szyfrowania danych przed ich wysłaniem do chmury (klient-side encryption).
W tradycyjnej kryptografii symetrycznej każdy użytkownik stosuje własny, losowy klucz oraz losowy wektor inicjalizujący IV. W efekcie dwa identyczne pliki zaszyfrowane przez dwóch różnych użytkowników stają się całkowicie odmiennymi ciągami pseudolosowych bajtów. Uniemożliwia to dostawcy chmury jakąkolwiek deduplikację, prowadząc do marnotrawstwa przestrzeni dyskowej i wyższych kosztów usługi.
Odpowiedzią na ten dylemat jest technika zbieżnego szyfrowania (Convergent Encryption, CE). W technice tej klucz szyfrujący K wyprowadzany jest w sposób deterministyczny ze skrótu kryptograficznego samej wiadomości: K = SHA256(M). Szyfrowanie realizowane jest algorytmem symetrycznym AES (np. w trybie CTR lub GCM) z wektorem IV również wyliczonym ze skrótu danych.
W rezultacie dowolny użytkownik posiadający dokładnie ten sam plik wygeneruje identyczny klucz oraz identyczny szyfrogram C. Dostawca chmury może bezpiecznie zdeduplikować szyfrogramy na poziomie bloków, nie mając wglądu w tekst jawny bez znajomości danych.
W tym zadaniu zaimplementujesz procedurę zbieżnego szyfrowania, zamodelujesz wielodostęp użytkowników i przeanalizujesz kompromis bezpieczeństwa.
Co ma wykonać student / grupa
Pracę rozpoczynasz od utworzenia katalogu convergent_lab w terminalu środowiska z pakietem pycryptodome lub biblioteką cryptography. Tworzysz skrypt
convergent_storage.py modelujący wielodzierżawny magazyn chmurowy oraz dwóch niezależnych klientów Alice i Boba. Implementujesz funkcję
convergent_encrypt(plaintext), która w pierwszym kroku wylicza 256-bitowy skrót SHA-256 z danych wejściowych. Wygenerowany skrót traktowany jest bezpośrednio jako
symetryczny klucz AES-256, natomiast pierwsze 16 bajtów drugiego hasza służy jako deterministyczny wektor IV.
Wykonujesz szyfrowanie bloku za pomocą algorytmu AES w trybie CTR, uzyskując deterministyczny szyfrogram ciphertext. Implementujesz funkcję
convergent_decrypt(ciphertext, key), która odwraca operację i odzyskuje oryginalny tekst jawny. Generujesz wspólny plik testowy zawierający poufny raport finansowy i symulujesz jego
przesłanie do chmury najpierw przez Alice, a następnie przez Boba. Weryfikujesz, że szyfrogram wygenerowany przez Boba jest identyczny co do bajta z szyfrogramem Alice, co pozwala
chmurze zapisać blok tylko raz.
Zapisujesz klucz K w lokalnym bezpiecznym portfelu użytkownika zaszyfrowanym jego prywatnym hasłem głównym (Master Password). Analizujesz podatność zbieżnego szyfrowania na
atak słownikowy (confirmation-of-a-file attack), gdy atakujący zgaduje zawartość znanego pliku. Wykazujesz w sprawozdaniu, w jaki sposób schemat DupLESS z serwerem KSF ogranicza tę
podatność, oraz dokumentujesz działanie kodu.
Przykładowe kroki do wykonania jako sugestia
-
W terminalu utwórz katalog roboczy:
mkdir -p ~/convergent_lab
&& cd ~/convergent_lab.
-
Upewnij się o dostępności biblioteki kryptograficznej w Pythonie:
python3 -c
'import cryptography' || dnf install -y python3-cryptography.
- Utwórz plik skryptu:
nano convergent_engine.py.
-
Zaimportuj moduły: os, hashlib, json z pakietu
cryptography.hazmat.primitives.ciphers
(AES, CTR).
-
Zaimplementuj funkcję
derive_keys( plaintext): key
= hashlib.sha256( plaintext).digest(),
iv =
hashlib.sha256(key).digest()[:16].
-
Zaimplementuj funkcję
ce_encrypt( plaintext): wyprowadź klucz i
IV, zaszyfruj dane AES-CTR, zwróć
(ciphertext, key).
-
Zaimplementuj funkcję
ce_decrypt( ciphertext, key):
wyprowadź deterministyczny IV, odszyfruj dane
AES-CTR, zwróć plaintext.
-
Zdefiniuj klasę CloudStorage ze słownikiem deduplikacji:
storage = {} (mapującym
hash_szyfrogramu -> ciphertext).
-
Przygotuj poufny dokument wspólny:
doc =
b'Raport audytu bezpieczenstwa infrastruktury storage UAFM 2026'.
-
Zasymuluj działanie Klienta 1 (
Alice): zaszyfruj dokument, wyślij szyfrogram do chmury, zapisz klucz w lokalnym
magazynie Alice.
- Chmura rejestruje nowy unikalny blok i zwiększa licznik alokacji o 1.
-
Zasymuluj działanie Klienta 2 (
Bob): zaszyfruj ten sam dokument metodą
CE, wyślij szyfrogram do chmury.
-
Chmura wykrywa duplikat szyfrogramu:
deduplication_hit =
True, przestrzeń fizyczna nie ulega zwiększeniu.
-
Sprawdź,
czy Bob może bez przeszkód odszyfrować plik ze swojego lokalnego klucza: assert
ce_decrypt(szyfrogram_z_chmury, klucz_boba)
== doc.
- Zasymuluj próbę ataku podsłuchiwacza chmury: wykaż, że bez znajomości tekstu jawnego chmura widzi jedynie losowy szyfrogram.
-
Przetestuj podatność Dictionary Attack: sprawdź,
jak atakujący znający skończony zbiór dokumentów może
potwierdzić obecność pliku.
- Wykonaj zrzuty ekranu kodu źródłowego, symulacji wielodostępnej oraz weryfikacji deduplikacji zaszyfrowanych bloków.
-
Sformułuj wnioski opisujące kompromis pomiędzy semantycznym bezpieczeństwem
CPA a deduplikowalnością w chmurze.
Kontrola zaliczenia (checklist):
- Uruchomiono convergent encryption i zachowano log: K=H(M), ten sam blok → ten sam szyfrogram (dedup działa), serwer bez plaintextu.
- Dołączono kod (własne 20–40 linii): KDF z bloku, szyfrowanie deterministyczne, indeks serwerowy.
- Przeprowadzono test pozytywny (duplikat deduplikowany) i negatywny (atak potwierdzenia wykazany i opisany + mitygacja DupLESS).
- Opisano w 3–5 zdaniach: konflikt prywatność vs dedup, CE jako kompromis, granice (confirmation attack).
Wariant offline (fallback): Praca w pełni offline na wektorach ze startera w lokalnym Pythonie 3 (hashlib/struct); mdadm/smartctl zastąp logiem skryptu; dołącz kod (szkielet + własne 20–40 linii) i log z konsoli.
Sugerowane wnioski i podsumowanie - co student ma osiągnąć
Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:
- Zrozumienie fundamentalnego konfliktu pomiędzy semantycznym szyfrowaniem a globalną deduplikacją w chmurze.
- Praktyczna umiejętność implementacji zbieżnego szyfrowania (Convergent Encryption) z kluczami deterministycznymi K = H(M).
- Weryfikacja zachowania deduplikacji blokowej po stronie serwera chmurowego przy braku dostępu do tekstu jawnego.
- Świadomość ograniczeń bezpieczeństwa CE (podatność na atak potwierdzenia pliku) oraz znajomość metod mitygacji (DupLESS).