Jeśli otrzymam JWT i mogę dekodować ładunek, jak to jest bezpieczne? Czy nie mogę po prostu wyciągnąć tokena z nagłówka, zdekodować i zmienić informacje o użytkowniku w ładunku i odesłać go z tym samym poprawnym, zakodowanym sekretem?
Wiem, że muszą być bezpieczne, ale naprawdę chciałbym zrozumieć technologie. czego mi brakuje?
security
jwt
express-jwt
PixMach
źródło
źródło
md5('original messaged' + secret) != md5('changed message' + secret)
więc jeśli ktoś zmieni wiadomość, możesz ją wykryćOdpowiedzi:
JWT mogą być podpisane, zaszyfrowane lub oba jednocześnie. Jeśli token jest podpisany, ale nie zaszyfrowany, każdy może odczytać jego zawartość, ale gdy nie znasz klucza prywatnego, nie możesz go zmienić. W przeciwnym razie odbiorca zauważy, że podpis nie będzie już zgodny.
Odpowiedz na twój komentarz: Nie jestem pewien, czy rozumiem twój komentarz we właściwy sposób. Dla pewności: czy znasz i rozumiesz podpisy cyfrowe? Wyjaśnię krótko jeden wariant (HMAC, który jest symetryczny, ale jest wiele innych).
Załóżmy, że Alice chce wysłać JWT do Boba. Oboje znają jakiś wspólny sekret. Mallory nie zna tej tajemnicy, ale chce ingerować i zmieniać JWT. Aby temu zapobiec, Alice oblicza
Hash(payload + secret)
i dołącza to jako podpis.Po otrzymaniu wiadomości Bob może również obliczyć,
Hash(payload + secret)
aby sprawdzić, czy podpis pasuje. Jeśli jednak Mallory coś zmieni w treści, nie będzie w stanie obliczyć pasującego podpisu (co byłobyHash(newContent + secret)
). Nie zna tajemnicy i nie ma sposobu, aby ją znaleźć. Oznacza to, że jeśli coś zmieni, sygnatura nie będzie już zgodna, a Bob po prostu nie zaakceptuje JWT.Załóżmy, że wysyłam innej osobie wiadomość
{"id":1}
i podpisuję jąHash(content + secret)
. (+ to tylko konkatenacja tutaj). Korzystać z funkcji SHA256 ziemniaczane i podpis pojawia się:330e7b0775561c6e95797d4dd306a150046e239986f0a1373230fda0235bda8c
. Teraz twoja kolej: wciel się w Mallory i spróbuj podpisać wiadomość{"id":2}
. Nie możesz, bo nie wiesz, którego sekretu użyłem. Jeśli podejrzewam, że odbiorca zna sekret, MOŻE obliczyć podpis każdej wiadomości i sprawdzić, czy jest poprawny.źródło
Możesz przejść do
jwt.io
, wkleić token i przeczytać zawartość. To początkowo denerwuje wielu ludzi.Krótka odpowiedź brzmi: JWT nie zajmuje się szyfrowaniem. Dba o walidację. Oznacza to, że zawsze może uzyskać odpowiedź na „Czy zmieniono treść tego tokena”? Oznacza to, że manipulowanie tokenem JWT przez użytkownika jest daremne, ponieważ serwer będzie wiedział i zignorował token. Serwer dodaje podpis oparty na ładunku podczas wydawania tokena klientowi. Później weryfikuje ładowność i pasujący podpis.
Logiczne pytanie brzmi: jaka jest motywacja, aby nie zajmować się zaszyfrowanymi treściami?
Najprostszym powodem jest założenie, że jest to w większości rozwiązany problem. Jeśli masz do czynienia z klientem takim jak na przykład przeglądarka internetowa, możesz przechowywać tokeny JWT w pliku cookie, który jest
secure
(nie jest przesyłany przez HTTP, tylko przez HTTPS) ihttpOnly
(nie może być odczytany przez Javascript) i rozmawia z serwerem przez szyfrowany kanał (HTTPS). Gdy wiesz, że masz bezpieczny kanał między serwerem a klientem, możesz bezpiecznie wymieniać JWT lub cokolwiek innego.To sprawia, że sprawa jest prosta. Prosta implementacja ułatwia adopcję, ale pozwala również każdej warstwie robić to, co najlepiej (niech HTTPS obsługuje szyfrowanie).
JWT nie jest przeznaczony do przechowywania poufnych danych. Gdy serwer otrzyma token JWT i potwierdzi go, można wyszukać ID użytkownika we własnej bazie danych w celu uzyskania dodatkowych informacji dla tego użytkownika (takich jak uprawnienia, adres pocztowy itp.). Dzięki temu JWT ma niewielkie rozmiary i pozwala uniknąć przypadkowego wycieku informacji, ponieważ wszyscy wiedzą, że nie należy przechowywać poufnych danych w JWT.
Nie różni się zbytnio od sposobu działania samych plików cookie. Pliki cookie często zawierają niezaszyfrowane ładunki. Jeśli używasz HTTPS, wszystko jest w porządku. Jeśli tak nie jest, wskazane jest szyfrowanie poufnych plików cookie. Nieprzestrzeganie tego oznacza, że możliwy jest atak typu man-in-the-middle - serwer proxy lub dostawca usług internetowych odczytuje pliki cookie, a następnie odtwarza je później, udając, że jesteś tobą. Z podobnych powodów JWT należy zawsze wymieniać na bezpieczną warstwę, taką jak HTTPS.
źródło
Zawartość tokena internetowego Json (JWT) nie jest z natury bezpieczna, ale ma wbudowaną funkcję weryfikacji autentyczności tokena. JWT to trzy skróty oddzielone kropkami. Trzeci to podpis. W systemie klucza publicznego / prywatnego wystawca podpisuje podpis tokena kluczem prywatnym, który można zweryfikować tylko za pomocą odpowiedniego klucza publicznego.
Ważne jest, aby zrozumieć różnicę między emitentem a weryfikatorem. Odbiorca tokena jest odpowiedzialny za jego weryfikację.
Istnieją dwa krytyczne kroki w bezpiecznym korzystaniu z JWT w aplikacji internetowej: 1) wysyłaj je zaszyfrowanym kanałem i 2) weryfikuj podpis natychmiast po jego otrzymaniu. Asymetryczny charakter kryptografii klucza publicznego umożliwia weryfikację podpisu JWT. Klucz publiczny sprawdza, czy JWT został podpisany przez odpowiadający mu klucz prywatny. Żadna inna kombinacja kluczy nie może wykonać tej weryfikacji, zapobiegając w ten sposób próbom podszywania się. Wykonaj te dwa kroki, a my z matematyczną pewnością możemy zagwarantować autentyczność JWT.
Więcej informacji: Jak klucz publiczny weryfikuje podpis?
źródło
Od samego początku dyskutujmy:
JWT to bardzo nowoczesne, proste i bezpieczne podejście, które obejmuje także tokeny Json Web. Tokeny internetowe Json to bezpaństwowe rozwiązanie do uwierzytelniania. Nie ma więc potrzeby przechowywania żadnego stanu sesji na serwerze, co oczywiście jest idealne dla spokojnych interfejsów API. Spokojne interfejsy API powinny zawsze być bezstanowe, a najczęściej stosowaną alternatywą dla uwierzytelniania za pomocą JWT jest po prostu przechowywanie stanu logowania użytkownika na serwerze za pomocą sesji. Ale oczywiście nie jest to zgodne z zasadą mówiącą, że uspokajające interfejsy API powinny być bezstanowe i dlatego rozwiązania takie jak JWT stały się popularne i skuteczne.
Teraz dowiedzmy się, jak uwierzytelnianie faktycznie działa z tokenami Json Web. Zakładając, że mamy już zarejestrowanego użytkownika w naszej bazie danych. Tak więc klient użytkownika zaczyna od wysłania żądania postu z nazwą użytkownika i hasłem, aplikacja sprawdza następnie, czy użytkownik istnieje i czy hasło jest poprawne, a następnie aplikacja wygeneruje unikalny token Json Web tylko dla tego użytkownika.
Token jest tworzony przy użyciu tajnego ciąg , który jest przechowywany na serwerze . Następnie serwer wysyła ten JWT z powrotem do klienta, który zapisze go w pliku cookie lub w lokalnej pamięci.
W ten sposób użytkownik jest uwierzytelniany i zasadniczo zalogowany do naszej aplikacji bez pozostawiania żadnego stanu na serwerze.
Tak więc serwer nie wie, który użytkownik jest faktycznie zalogowany, ale oczywiście użytkownik wie, że jest zalogowany, ponieważ ma ważny token Json Web, który jest trochę jak paszport umożliwiający dostęp do chronionych części aplikacji.
Więc ponownie, aby upewnić się, że masz pomysł. Użytkownik jest zalogowany, gdy tylko odzyska swój unikalny ważny Json Web Token, który nie jest zapisany nigdzie na serwerze. Dlatego proces ten jest całkowicie bezpaństwowy.
Następnie za każdym razem, gdy użytkownik chce uzyskać dostęp do chronionej trasy, na przykład danych swojego profilu użytkownika. Wysyła swój Json Web Token wraz z prośbą, więc to trochę jak pokazanie swojego paszportu, aby uzyskać dostęp do tej trasy.
Gdy żądanie trafi na serwer, nasza aplikacja sprawdzi, czy token sieci Web Jsona jest rzeczywiście prawidłowy, a jeśli użytkownik naprawdę jest tym, za kogo się podaje, dobrze, wtedy żądane dane zostaną wysłane do klienta, a jeśli nie, to nastąpi być błędem informującym użytkownika, że nie ma on dostępu do tego zasobu.
Cała ta komunikacja musi odbywać się przez https, więc bezpieczny szyfrowany HTTP, aby uniemożliwić każdemu dostęp do haseł lub tokenów Json Web. Tylko wtedy mamy naprawdę bezpieczny system.
Tak więc token WWW Jsona wygląda jak lewa część tego zrzutu ekranu, który został pobrany z debugera JWT na stronie jwt.io. Zasadniczo jest to ciąg kodujący złożony z trzech części. Nagłówek, ładunek i podpis Teraz nagłówek to tylko niektóre metadane dotyczące samego tokena, a ładunek to dane, które możemy zakodować w tokenie, dowolne dane, które naprawdę chcemy. Im więcej danych chcemy tutaj zakodować, tym większy JWT. W każdym razie te dwie części są zwykłym tekstem, który zostanie zakodowany, ale nie zaszyfrowany.
Aby każdy mógł je odkodować i odczytać , nie możemy przechowywać tutaj żadnych wrażliwych danych. Ale to wcale nie jest problem, ponieważ w trzeciej części, a więc w podpisie, rzeczy naprawdę stają się interesujące. Podpis jest tworzony przy użyciu nagłówka, ładunku i klucza tajnego zapisanego na serwerze.
Cały proces nazywany jest podpisywaniem tokenu internetowego Json . Algorytm podpisywania pobiera nagłówek, ładunek i klucz tajny, aby utworzyć unikalny podpis. Więc tylko te dane plus sekret mogą stworzyć ten podpis, dobrze? Następnie wraz z nagłówkiem i ładunkiem podpis ten tworzy JWT, który następnie jest wysyłany do klienta.
Gdy serwer otrzyma JWT w celu udzielenia dostępu do chronionej trasy, musi go zweryfikować, aby ustalić, czy użytkownik naprawdę jest tym, za kogo się podaje. Innymi słowy, sprawdzi, czy nikt nie zmienił nagłówka i danych ładunku tokena. Zatem ponownie, ten krok weryfikacji sprawdzi, czy żadna strona trzecia nie zmieniła ani nagłówka, ani ładunku tokenu Json Web.
Jak zatem działa ta weryfikacja? Cóż, w rzeczywistości jest to całkiem proste. Po otrzymaniu JWT weryfikacja zajmie jego nagłówek i ładunek, a wraz z kluczem tajnym, który jest nadal zapisywany na serwerze, w zasadzie tworzy podpis testowy.
Ale oryginalny podpis, który został wygenerowany przy pierwszym tworzeniu JWT, wciąż znajduje się w tokenie, prawda? I to jest klucz do tej weryfikacji. Ponieważ teraz wszystko, co musimy zrobić, to porównać podpis testowy z podpisem oryginalnym. A jeśli podpis testowy jest taki sam jak podpis oryginalny, oznacza to, że ładunek i nagłówek nie zostały zmodyfikowane.
Ponieważ gdyby zostały zmodyfikowane, podpis testowy musiałby być inny. Dlatego w tym przypadku, gdy nie nastąpiła zmiana danych, możemy następnie uwierzytelnić użytkownika. I oczywiście, jeśli te dwa podpisy są faktycznie różne, to znaczy, że ktoś manipulował danymi. Zwykle poprzez zmianę ładunku. Ale ta osoba trzecia manipulująca ładunkiem nie ma oczywiście dostępu do tajemnicy, więc nie mogą podpisać JWT. Oryginalny podpis nigdy nie będzie odpowiadał zmanipulowanym danym. Dlatego weryfikacja zawsze zakończy się niepowodzeniem. I to jest klucz do uruchomienia całego systemu. To magia sprawia, że JWT jest tak proste, ale także niezwykle potężne.
źródło
Tylko prywatny klucz JWT, który znajduje się na twoim serwerze, odszyfruje zaszyfrowany JWT. Ci, którzy znają privateKey, będą mogli odszyfrować zaszyfrowany JWT.
Ukryj klucz prywatny w bezpiecznej lokalizacji na serwerze i nigdy nie mów nikomu o kluczu prywatnym.
źródło
Dla osób, które nie mogą sobie pozwolić na drogie zapytania do bazy danych, tak jak ja, jedną z opcji zachowania poufnych danych (przywilejów użytkownika itp.) Jest to, że podczas generowania JWT możesz zaszyfrować te dane i dołączyć je do tokena JWT. (Zachowaj klucz szyfrowania w wewnętrznej bazie danych)
Jeśli chcesz odczytać poufne informacje, możesz wysłać token JWT do wewnętrznej bazy danych i odszyfrować je, a następnie odzyskać informacje. W ten sposób nie musisz przeprowadzać wyszukiwania DB ani mieć poufnych informacji nagich w interfejsie za pomocą tokena JWT
źródło
Sugerowałbym przyjrzenie się JWE przy użyciu specjalnych algorytmów, których nie ma w pliku jwt.io do deszyfrowania
Link referencyjny: https://www.npmjs.com/package/node-webtokens
Ta odpowiedź może być za późno lub być może już znalazłeś drogę, ale nadal uważam, że byłaby pomocna dla ciebie i innych.
Prosty przykład, który stworzyłem: https://github.com/hansiemithun/jwe-example
źródło