Potencjalna podatność podczas szyfrowania AES256

Potencjalna podatność podczas szyfrowania AES256
dymul
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad rok
  • Postów:182
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

edytowany 1x, ostatnio: dymul
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
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

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
msm
Administrator
  • Rejestracja:prawie 16 lat
  • Ostatnio:4 miesiące
4

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

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

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

Kopiuj
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

Kopiuj
poprawnytoken_2018-07-14

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

Kopiuj
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.
edytowany 5x, ostatnio: msm
jarekczek
Możesz napisać wprost, czy mając IV (stała wartość) i skończoną liczbę tokenów da się uzyskać klucz? Nie do końca zrozumiałem.
msm
Napisałem - nie (nie ma żadnej możliwości żeby ktos był w stanie odzyskać IV albo klucz bez niczego). Ale to nie jest jedyny atak jaki się da zrobić na token - np. może sie zdarzyć że ktoś będzie mógł podrobić/spoofować token na podstawie innego tokenu, ale bez znajomosci klucza. W tym przypadku nie widzę takiej możliwości (chyba że ktoś bardzo dziwnie parsowanie zaimplementował), ale możliwe że ktoś sprytniejszy ode mnie ją znajdzie - dlatego polecałbym użycie HMAC czyli rozwiązania dedykowanego do takich problemów.
dymul
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad rok
  • Postów:182
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.

msm
Powodzenia! :P
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)