Potencjalna podatność podczas szyfrowania AES256

0

Cześć, problem dotyczy potencjalnej podatności podczas generowania tokena szyfrowanego szyfrem AES256, na którą natrafiłem w jednym z projektów. Nie jestem do końca pewien czy to faktycznie jest podatność, dlatego chciałbym poznać wszą opinię.

Cała autoryzacja opiera się na założeniu, że jeżeli potrafisz wygenerować token to jesteś tym za kogo się podajesz. Ze względu na symetryczność szyfru zarówno klucz (KEY), jak i wektor inicjalizacyjny (IV) muszą być współdzielone pomiędzy systemy (tym, który się autoryzuje i tym autoryzującym). Procedura generowania tokena i autoryzacji wygląda następująco (Zarówno KEY, jak i IV mają po 16 bajtów):

  1. Kodujemy KEY do Base64 -> otrzymujemy KEY_B64.
  2. Tworzymy wiadomość przeznaczona do zaszyfrowania, składającą się z zakodowanego klucza (KEY_B64), delimitera (DEL) i aktualnego czasu w określonym formacie tekstowym (DATE_TIME), wynikowa wiadomość ma postać KEY_B64 + DEL + DATE_TIME
  3. Wiadmość szyfrujemy AESem (AES/CBC/PKCS5Padding) z wykorzystaniem KEY i IV, po czym kodujemy do Base64.
  4. Tak otrzymany token przesyłamy odbiorcy.
  5. Odbiorca dekoduje token z Base64, przeprowadza deszyfrowanie używając KEY i IV i otrzymuje wiadomość.
  6. Jeżeli KEY się zgadza a czas użyty do jako DATE_TIME jest nie starszy niż określona wartość dostęp jest przyznawany.

Pytania:

  1. Zakładając, że potencjalny atakujący wie to wszystko, a nie zna jedynie KEY i IV to czy jest w stanie je odtworzyć dysponując skończoną liczbą tokenów? Chodzi mi głównie o to, czy fakt szyfrowania klucza kluczem ułatwia przeprowadzenie ataku? Czy może obniżenie skuteczności jest tutaj znikome?
  2. Czy odwrócenie kolejności elementów w wiadomości (tzn. DATE_TIME + DEL + KEY_B64) coś zmienia? W tym układzie każdy token byłby znacząco różny od poprzedniego, obecnie początek każdego tokena jest taki sam.

Wołam @Shalom, @msm, @Gynvael Coldwind

2
  1. Bez różnicy, chociaż nie do końca rozumiem po co szyfrować klucz samym sobą
  2. Gdyby IV było losowe, doklejane do każdego ciphertextu to w przypadku 2 można by fałszować tokeny, flipując sobie bity w IV, bo te zmieniałyby timestamp
4

Generalnie szyfrowanie klucza samym sobą niewiele coś zmienia (przynajmniej w przypadku AES i jakiegokolwiek sensownego szyfru symetrycznego).

aes_encrypt(key, base64(key) + "_" + datetime)

Jest mniej więcej tak samo odporne na podrobienie jak:

aes_encrypt(key, "goodtoken_" + datetime)

Jeśli IV nie jest w wiadomosci tylko jest ustalony z góry (a tak wynika z Twojej wypowiedzi) to nie ma żadnej możliwości żeby ktos był w stanie odzyskać IV albo klucz bez niczego. Można odzyskać IV znając klucz, ale to żaden atak (IV równie dobrze może być publiczny albo ustawiony na same zera, to nie element bezpieczeństwa tylko szczegół techniczny trybu CBC).

Odnośnie praktycznego ataku, dużo zależy od tego jak jest zaimplementowany parser tych danych. Ciągle jest to podatne na ataki polegające na byteflippingu, czyli z

poprawnytoken_2018-07-14

można by uzyskać przy odpowiedniej gimnastyce coś w rodzaju (nowsza data ale zniszczona pierwsza część tokenu):

8ę&^ęπ„8aþken_2021-07-14

W tym przypadku ciężko mi sobie wyobrazić żeby ktoś zrobił tu coś co pozwalałoby taki atak wykorzystać. Ale w przypadku bardziej skomplikowanych formatów (np. JSON albo chociaż urlencoding) szansa na to że ktoś zdeterminowany to wykorzytsa rośnie wykładniczo.


Ale tak w ogóle, to strasznie przekomplikowany ten system.

  1. Encryption is not authentication (nawet jeśli w tym przypadku nie wynika z tego jeszcze żaden oczywisty atak)
  2. Po co to base64 i separator w base64(key) + "_" + datetime? Nie szkodzi w niczym, ale też widać że nikt tego nie przemyślał do końca (skoro klucz ma zawsze 16 bajtów to nie trzeba enkodowań ani separatorów).
  3. Z wiadomości wynika że IV jest też traktowany jako sekret. Niepotrzebna komplikacja, można dać tam dowolną ustaloną wartość.
  4. Dlaczego nie zrobić tego po ludzku, np. korzystająć z https://en.wikipedia.org/wiki/Message_authentication_code? :P. HMAC rozwiązuje wszystkie powyższe problemy, nie wymaga IV, jest bardziej debugowalne (można umiescić timestamp plaintextem jeśli się chce) oraz jest zaprojektowany specjalnie po to żeby działać dobrze w takich przypadkach.
0

Dzięki za wyczerpujące odpowiedzi.

Ale tak w ogóle, to strasznie przekomplikowany ten system.

Tak to się niestety kończy jak się pisze projekt na kolanie, bez przemyślenia bo terminy gonią. Ja się za jakiegoś szczególnego majstra (szczególnie w security) nie uważam a i tak ilość potworków w designie a raczej jego braku mnie przeraża. Ale spoko, ewakuacja już zarządzona :D
Odnośnie tego co wypunktował @msm - po przemyśleniu i doczytaniu podpisuję się pod tym obiema rękami.

1 użytkowników online, w tym zalogowanych: 0, gości: 1