Pytanie:
Jak zabezpieczyć hasła przez HTTP?
FireCubez
2018-11-09 19:57:16 UTC
view on stackexchange narkive permalink

Powiedz, że moje hasło to abc . Chcę wysłać go do serwera przez HTTP.

Mógłbym wysłać go w postaci zwykłego tekstu i pozwolić serwerowi go zaszyfrować i porównać z wpisami w swojej bazie danych, ale wtedy każdy, kto może zobaczyć ruch przez to połączenie zobaczyłby hasło w postaci zwykłego tekstu.

Więc mógłbym wtedy zaszyfrować je po stronie klienta i pozwolić serwerowi po prostu porównać je bez mieszania, ponieważ jest już zaszyfrowane (lub serwer mógłby nawet podwoić hash, ale bez różnicy w ta sytuacja). Ale z drugiej strony każdy, kto widzi ruch, zobaczy zaszyfrowane hasło, a następnie wyśle ​​zaszyfrowane hasło do serwera, a serwer je zaakceptuje.

Jak wysyłać hasła przez HTTP? Czy muszę zaimplementować jakiś algorytm szyfrowania, taki jak szyfrowanie z kluczem publicznym RSA? A może to niemożliwe?

Metoda powinna być dostępna w każdej przeglądarce.

Dlaczego nie możesz po prostu użyć TLS?Naprawdę nie ma innego sposobu, aby zrobić to bezpiecznie.
@AndrolGenhald Mógłbym, to tylko dowód słuszności koncepcji.Jeśli nie ma innego sposobu, aby zrobić to bezpiecznie, to jest odpowiedź, której szukałem.Powinieneś zamieścić to jako odpowiedź
Nie potrzebujesz natywnego TLS - teoretycznie możesz zaimplementować TLS przez HTTP - ale nie byłoby to praktycznie praktyczne.
@AndrolGenhald Nie ma dobrego powodu, aby nie używać TLS, ale uważam, że istnieje wiele innych sposobów, aby zrobić to bezpiecznie.Na przykład można tunelować http przez ssh.
Może spróbuj użyć ECDHE do bezpiecznej wymiany kluczy?
@emory Plakat wyjaśnił, że kontekstem jest komunikacja między przeglądarką internetową a serwerem HTTP, a nie niestandardowa aplikacja do serwera niestandardowego.
Czy to prawdziwy problem, z którym się mierzysz, czy tylko eksperyment myślowy?
@whatsisname Stwierdziłem, że w poprzednim komentarzu to tylko eksperyment
Chociaż nienawidzę, gdy pytasz A, a ludzie odpowiadają „po prostu użyj B”, będę musiał zgodzić się z wieloma odpowiedziami „po prostu użyj TLS”, ponieważ jest to najprostszy sposób rozwiązania praktycznego problemu.Powiedziałeś teraz, że _nie_ chodzi o problem praktyczny, ale „tylko do eksperymentu”, więc możesz przeczytać o [protokołach zerowej wiedzy] (https://en.wikipedia.org/wiki/Zero-knowledge_proof), które robią cochcesz.
Oryginalna implementacja hasła programu MSN Messenger była odpowiednia dla tego scenariusza.Serwer wysłał Ci „sól”, za pomocą której zaszyfrowałeś swoje hasło i odesłałeś hash z powrotem na serwer.Ponieważ serwer znał Twoje hasło, mógł wykonać te same obliczenia.Serwer był odpowiedzialny za upewnienie się, że nie użyje ponownie soli
FWIW, nawet jeśli uda Ci się bezpiecznie przesłać hasła, nic nie osiągniesz.Reszta sesji jest niezaszyfrowana, można ją łatwo ukraść lub zmodyfikować.Nawet jeśli możesz bezpiecznie udowodnić, że jesteś Bobem, w momencie, gdy to się stanie, Alicja może ukraść twoją sesję i być Bobem tak długo, jak zechce.
@curiousguy Jeśli OP uruchomił `ssh -L 127.0.0.1:8080:intra.example.com:80 gw.example.com`, a następnie przeszedł do http://127.0.0.1:8080, połączenie zostanie zaszyfrowane, a hasła zabezpieczone.(1) Zakłada się, że OP może ssh do gw.example.com i (2) może serwer WWW nie odpowiada na żądania lokalne.Ten przykład może / może nie działać dla OP, ale twierdzenie, że TLS jest jedynym sposobem, jest błędne.
@emory Czy to nie _w efekcie_ przy używaniu TLS, ale po prostu mając `ssh` zrobi to zamiast implementować go bezpośrednio w kliencie?I czy połączenie z „gw.example.com” do prawdziwego serwera WWW nadal byłoby podatne na podsłuchiwanie?
@TripeHound Poleciłbym tylko używanie TLS i nie martwienie się o te problemy.Ale jeśli w efekcie używa TLS, ale ssh robi to zamiast implementować go bezpośrednio w kliencie, wtedy połączenie z prawdziwym serwerem WWW nie byłoby podatne na podsłuchiwanie.
Dziewięć odpowiedzi:
tim
2018-11-09 20:08:48 UTC
view on stackexchange narkive permalink

Nie możesz.

Aby bezpiecznie przesyłać informacje niezabezpieczonym kanałem, potrzebujesz szyfrowania.

Szyfrowanie symetryczne przestało działać, ponieważ najpierw musiałbyś przetransportować klucz, czego nie możesz bezpiecznie zrobić przez niezabezpieczony kanał [*].

To pozostawia klucz publiczny kryptografia. Mógłbyś oczywiście rozwinąć swój własny, ale nie chcesz być Dave'em, więc to się skończyło, co pozostawia cię z HTTPS.

[*] Można oczywiście spróbować użyć bezpiecznego kanału do wymiany klucza, na przykład fizycznej wymiany klucza. Następnie możesz użyć tajnego klucza kryptograficznego, takiego jak Kerberos.

Nie mógłbyś tego dwa razy haszować?Raz po stronie klienta, raz na serwerze?
@NathanMerrill - [Hashowanie hasła po stronie klienta sprawia, że hash jest hasłem] (https://security.stackexchange.com/questions/8596/https-security-should-password-be-hashed-server-side-or-po stronie klienta) (brak schematu zawierającego dodatkowe informacje).Jednak samo zabezpieczenie hasła jest bezwartościowe - musisz przynajmniej uwierzytelnić ** kanał **, w przeciwnym razie atakujący może podszyć się pod oba końce rozmowy, nawet nie znając hasła.
To jest mylące.Tak, możesz.To pytanie dotyczy tego, jak zabezpieczyć hasła, gdy nie możesz używać protokołu HTTP.Zła polityka firmy, źle skonfigurowana zapora może wymusić użycie protokołu HTTP.W takich sytuacjach wymiana certyfikatów (IPsec TLS SCRAM itp.) Przez kanał boczny jest możliwa i powinna być odpowiedzią.Odpowiedz na pytanie, zamiast udzielać porad, o które nie prosiłeś.
@noɥʇʎԀʎzɐɹƆ Wspomniałem już, że istnieją alternatywy, w których można użyć bezpiecznego kanału bocznego (co jest wymagane w przypadku alternatyw wymienionych w innych odpowiedziach).Ale tak naprawdę nie o to chodzi w pytaniu („Ta metoda powinna być użyteczna w każdej przeglądarce”).Zdecydowanie istnieją przypadki użycia tych alternatyw, ale „nie możemy używać HTTPS, ponieważ nasza infrastruktura jest zbyt zepsuta” nie powinno być jednym z nich.
Zgadzam się z głównym punktem - nie da się tego zrobić.Ale dodałbym, że nawet jeśli jesteś Dave'em i rzucasz własną kryptowalutą, to nie pomoże.Kod, który wykonuje kryptografię, jest dostarczany przez HTTP i dlatego może zostać zmieniony.
AndrolGenhald
2018-11-09 20:09:53 UTC
view on stackexchange narkive permalink

TLS to naprawdę jedyny sposób, aby to zrobić.

Ale co, jeśli zaszyfruję go za pomocą JavaScript?

Atakujący może zmienić JavaScript, wyślij do klienta lub po prostu wstrzyknij własny JavaScript, który rejestruje wszystkie wprowadzone informacje.

Następnie użyję CSP i SRI, aby zapobiec dodawaniu skryptów i modyfikacji moich własnych skryptów.

Cieszę się, że korzystasz z nowoczesnych narzędzi do ochrony swojej witryny, ale SRI w niezabezpieczonym kontekście tak naprawdę chroni tylko przed włamaniem do zasobu zewnętrznego. Atakujący może po prostu zmodyfikować nagłówki CSP i tagi SRI.

Naprawdę nie da się tego zrobić bez szyfrowania od samego początku, a jedynym standardowym sposobem jest użycie TLS.

Melanie
2018-11-10 00:01:01 UTC
view on stackexchange narkive permalink

Chociaż zgadzam się, że powinieneś używać HTTPS, możesz uczynić go jeszcze bezpieczniejszym, używając mechanizmu uwierzytelniania Salted Challenge Response Authentication Mechanism (SCRAM, patrz RFC 5802) dla rzeczywistej wymiany uwierzytelniania.

Wdrożenie tego nie jest proste, ale sednem tego jest to, że zamiast wysyłać hasło do serwera, wysyłasz do serwera dowód, że znasz hasło. Ponieważ wyprowadzenie dowodu używa wartości jednorazowej od klienta i serwera, atakujący nie może ponownie użyć tego elementu (tak jak samo wysłanie skrótu).

Ma to kilka dodatkowych zalet korzystania z protokołu HTTPS z podstawowe uwierzytelnianie, które opisujesz:

  1. Serwer tak naprawdę nigdy nie widzi Twojego hasła podczas logowania. Jeśli komuś udało się wstawić złośliwy kod na serwer, nadal nie będzie wiedział, jakie jest Twoje hasło .
  2. Jeśli wystąpi błąd w implementacji HTTPS (pomyśl o Heartbleed), atakujący nadal nie będą w stanie uzyskać Twojego hasła. Ponieważ nawet po ominięciu TLS hasło nie jest dostępne.
  3. Jeśli z jakiegoś powodu nie możesz użyć HTTPS, jest to lepsze niż wysłanie hasła w postaci jawnej. Osoba atakująca nie będzie w stanie odgadnąć Twojego hasła na podstawie wymiany. To powiedziawszy, nadal powinieneś używać HTTPS, ponieważ obrona w głębi jest lepsza.

Uwaga , że jest to bezpieczne tylko wtedy, gdy klient jest w stanie wykonać SCRAM obliczenia bez pobierania kodu z serwera. Możesz dostarczyć grubego klienta lub użytkownicy mogą pisać własny kod, który kontrolują. Pobranie kodu SCRAM-u przez HTTP dałoby atakującemu możliwość zmodyfikowania kodu SCRAM-u w celu wysłania hasła w postaci zwykłego tekstu lub ujawnienia go w inny sposób.

Możesz to bezpiecznie zrobić za pomocą grubego klienta (aplikacji stacjonarnej lub mobilnej), który jest dystrybuowany w bezpieczny sposób.Jednak w przypadku cienkiego klienta w przeglądarce sam kod klienta jest również dostarczany przez HTTP, a jak zauważył @AndrolGenhald, atakujący w środku mogą przechwycić i zmienić go, aby wysłać do nich hasło.
@Zoltan To bardzo prawda, dziękuję za wyjaśnienie.Oryginalne pytanie nie określa, czy potrzebują cienkiego czy grubego klienta, więc moja odpowiedź nie miałaby zastosowania we wszystkich przypadkach.Ale myślę, że nawet w przypadku HTTP zapewnia to dodatkowe bezpieczeństwo.Atak przeszedł od szpiegowania ruchu do modyfikowania kodu.Nic nie do pokonania, więc nie byłoby to bezpieczne, ale może mniej złe?Myślę, że zarówno HTTPS, jak i SCRAM są bardzo korzystne.
Jeśli się zgadzasz, możesz rozważyć wspomnienie o tym ograniczeniu w swojej odpowiedzi.W przeciwnym razie bardzo mi się podoba twoja odpowiedź, ponieważ odpowiedź na wyzwanie była moją pierwszą myślą i żadna z pozostałych odpowiedzi o tym nie wspomniała.
Dziękuję, zaktualizowałem moją odpowiedź.Daj mi znać, jeśli uważasz, że przydałoby się dalsze wyjaśnienie!
Dla mnie wygląda dobrze, dzięki, przegłosowano.Należy jednak usunąć część „Podziękowania dla Zoltan”, ponieważ wyrażenia grzecznościowe, takie jak pozdrowienia, podpis i podziękowanie, są odradzane w pytaniach i odpowiedziach na stronach Stack Exchange, aby skupić się na treści.Aha, a przy okazji witamy w Stack Exchange!:)
@Melanie Masz całkowitą rację, że nawet z samym HTTP jest lepsze.Są napastnicy zdolni tylko do ataków pasywnych.Biorąc to pod uwagę, nie ma powodu, aby nie używać protokołu HTTPS w dzisiejszych czasach, gdy jest on bezpłatny.
Czy SCRAM wymaga, aby hasło było przechowywane na serwerze w sposób umożliwiający jego odzyskanie?Lub czy nadal można go solić + mieszać
@IanF1 Serwer musi znać tylko skrót hasła.Ponadto wszystkie przeglądarki, które znam, implementują podobny mechanizm: [HTTP Digest Authentication] (https://en.wikipedia.org/wiki/Digest_access_authentication), więc nawet z cienkim klientem można użyć tej metody.Z drugiej strony, skrót HTTP jest oparty na przestarzałych skrótach MD5, ale nie jestem pewien, jak bardzo jest z tego powodu niebezpieczny (MD5 nie jest zepsuty dla każdej aplikacji).
@Zoltan, Usunąłem podziękowanie.Chociaż nie lubię nie przyznawać kredytu tam, gdzie jest to należne, przypuszczam, że jest to tutaj w komentarzach.Dzięki jeszcze raz!
@Jost Używanie MD5 (lub jakiejś funkcji opartej na iteracji MD5 lub kompozycji z solą lub nazwą) do przechowywania lub sprawdzania haseł nie jest dziś ** bardziej zepsute niż kiedykolwiek **: obliczanie MD5 lub jakiejkolwiek iteracji MD5 może 't być uproszczone, a MD5 ^ 1000 nadal wymaga 1000 iteracji obliczeń i nie ma lepszego sposobu, aby stwierdzić, które x spełnia MD5 ^ 1000 (x) = y, niż wypróbowanie różnych wartości x lub metod opartych na wstępnie obliczonych listach, co jesttakże najlepsza metoda dla SHA1 lub nowszych funkcji skrótu.Nie dokonano tu żadnego teoretycznego ani praktycznego postępu.
Polynomial
2018-11-10 00:31:25 UTC
view on stackexchange narkive permalink

Zdecydowanie powinieneś wdrożyć TLS w tym przypadku.

Jeśli zdecydujesz się wymyślić system bezpieczeństwa transportu przez HTTP, ostatecznie i tak skończysz zaimplementowaniem zestawu funkcji TLS. Jest wiele pułapek, o których należy pamiętać podczas projektowania i wdrażania takiego systemu, które są dodatkowo wzmacniane, gdy zdecydujesz się wdrożyć system w języku, który nie oferuje wielu funkcji bezpieczeństwa.

Nawet jeśli zaimplementowałeś poprawną implementację protokołu kryptograficznego w JavaScript (co już jest dużym wyzwaniem), nie możesz polegać na tym, że implementacja jest odporna na ataki czasowe, a całość się psuje, jeśli ktoś ma wyłączone skrypty (np. z NoScriptem).

Generalnie powinieneś wybrać implementację, która składa się z najprostszych, dobrze zrozumiałych i zaufanych komponentów, które wymagają napisania najmniejszej ilości kodu krytycznego dla bezpieczeństwa. Cytując Andrew Tannenbauma:

Znaczna liczba problemów (w bezpieczeństwie aplikacji) jest spowodowana błędnym oprogramowaniem, które występuje, ponieważ dostawcy dodają coraz więcej funkcji do ich programy, co nieuchronnie oznacza więcej kodu, a tym samym więcej błędów.

Brian Williams
2018-11-09 22:03:34 UTC
view on stackexchange narkive permalink

Czy muszę zaimplementować jakiś algorytm szyfrowania, taki jak szyfrowanie z kluczem publicznym RSA?

Jeśli rozważasz wypróbowanie tego, równie dobrze możesz po prostu przejść całą drogę i użyć HTTPS. Ponieważ nie wydajesz się być ekspertem, szyfrowanie „na własną rękę” niewątpliwie będzie miało błędne implementacje, które czynią je niepewnym.

Pierre del Perugia
2018-11-10 15:38:45 UTC
view on stackexchange narkive permalink

Jest to całkiem możliwe.

Hasło musi być zaszyfrowane po stronie klienta, ale nie za pomocą funkcji statycznej. Poniższa metoda składa się z dwóch kroków i jest inspirowana uwierzytelnianiem dostępu Digest:

UWAGA: Serwer przechowuje HMAC Hasła i odpowiadającego mu Klucz ( Digest );

  1. Klient rozpoczyna od żądania numeru jednorazowego do serwera, serwer zwraca Klucz , a Nonce”;
  2. Klient oblicza: HMAC (HMAC ( Hasło , Klucz ), Nonce ) i wysyła go na serwer;
  3. Serwer oblicza: HMAC ( Digest , Nonce ) i porównuje z otrzymaną wartością.

To chroni Cię przed powtórką.

Widzę, że głównym celem nie jest ochrona przed podsłuchem, ale zapewnienie całkowitej pewności, że hasło w postaci zwykłego tekstu nie zostanie zapisane na serwer, nawet w dzienniku systemowym (patrz Twitter lub GitHub).

Uwaga: HMAC można zastąpić PBKDF2.

Następnie ktoś atakujący może wstrzyknąć jakiś kod, aby uzyskać hasło bezpośrednio z pliku ``.Szalony pomysł: „Niestety * tylko trochę * trudno jest obsługiwać protokół HTTPS na zarezerwowanych adresach IP. [Uruchom ten kod na swoim terminalu] (https://stackoverflow.com/a/7285256) i wklej wynik HMAC”.(oczywiście wyłącz wklejanie kopii, aby zapobiec wklejaniu na dłuższą metę).
CBHacking
2018-11-10 16:42:21 UTC
view on stackexchange narkive permalink

W rzeczywistości istnieje sposób na uwierzytelnienie użytkownika przez niezabezpieczone połączenie: protokół bezpiecznego zdalnego hasła (SRP). SRP jest specjalnie zaprojektowany, aby umożliwić klientowi uwierzytelnienie się na serwerze bez możliwości przechwycenia hasła klienta, a nawet ponownego odtworzenia uwierzytelnienia w celu późniejszego podszywania się pod klienta, bez względu na to, czy uwierzytelnianie się powiodło, czy nie. Ponadto pomyślne uwierzytelnienie za pomocą SRP tworzy wspólny tajny klucz, który jest znany zarówno klientowi, jak i serwerowi, ale MitM nie. Ten tajny klucz może być użyty do szyfrowania symetrycznego i / lub HMAC.

Jednakże istnieje szereg ograniczeń SRP:

  1. Użytkownik musi zarejestrować się w bezpiecznym moda, ponieważ proces rejestracji wymaga przesłania materiałów równoważnych hasłom (chociaż serwer nie musi ich przechowywać).
  2. Chociaż próba logowania SRP z niezaufanego serwera jest bezpieczna nie ujawni twojego hasła na tym serwerze i będziesz w stanie stwierdzić, że serwer nie ma twojego hasła w swojej bazie danych), ładowanie strony logowania z niezaufanego serwera nie jest bezpieczne (może to spowodować wysłanie strona, która przechwytuje każde naciśnięcie klawisza i gdzieś je wysyła).
  3. Chociaż udane uwierzytelnienie za pośrednictwem SRP generuje bezpieczny wspólny klucz tajny, kod, aby faktycznie użyć tego klucza w aplikacji internetowej, musiałby zostać załadowany z serwer, a osoba atakująca może manipulować tym kodem, aby ukraść klucz symetryczny i wprowadzić zmiany w żądaniach i odpowiedziach.

Innymi słowy, chociaż SRP może być przydatne w sytuacjach, gdy masz zaufanego klienta, który nie musi pobierać swojego kodu przez niezabezpieczone połączenie, a także masz inny bezpieczny sposób rejestracji użytkownika (ów), SRP nie nadaje się do aplikacji internetowych. Aplikacje internetowe zawsze pobierają swój kod z serwera, więc jeśli połączenie z serwerem nie jest bezpieczne, MitM (lub inny atakujący sieci, na przykład ktoś podszywający się pod DNS) może wstrzyknąć złośliwy kod do aplikacji internetowej, a Ty nie ma nic, ofiara, może to zrobić. Gdy ten kod już się pojawi, może przechwycić każde hasło lub inne wprowadzone dane, ukraść każdy wygenerowany klucz i manipulować wszelkimi żądaniami, które wysyłasz lub otrzymywanymi odpowiedziami, nawet bez Twojej wiedzy.

Christopher Schultz
2018-11-11 04:51:56 UTC
view on stackexchange narkive permalink

Z pewnością możliwe jest bezpieczne przesłanie hasła za pomocą protokołu HTTP. Jest na to nawet norma. Nazywa się HTTP-Digest i jest zdefiniowany w RFC 7616. Od dłuższego czasu jest częścią specyfikacji HTTP. Pierwotnie został zaprojektowany do używania tylko algorytmu skrótu wiadomości MD5 („haszowania”), ale późniejsze wersje standardu pozwalają klientowi i serwerowi negocjować, którego algorytmu użyć.

Niestety, istnieje wiele problemów ze skrótem HTTP, a najbardziej rażącym z nich jest to, że serwer musi mieć hasło w postaci zwykłego tekstu . Więc chociaż możliwe jest bezpieczne przekazywanie haseł za pomocą protokołu HTTP, nie jest możliwe bezpieczne przechowywanie haseł na serwerze podczas korzystania z niego. Zasadniczo nie jest to przydatne.

Jak powiedzieli inni, lepiej byłoby zaimplementować TLS, ponieważ rozwiązuje on wiele problemów w tym samym czasie i jest dość kompatybilny z nowszymi wersjami.

Richard N
2018-11-13 03:55:03 UTC
view on stackexchange narkive permalink

Jak powiedzieli inni, TLS! TLS! TLS! (i z przyzwoitą długością klucza)

Ale jeśli do implementacji musisz używać protokołu HTTP i dowolnego serwera, czy jest to do użytku programowego, czy do użytku przez ludzi? oparte na formularzach? I czy twoje zastosowania są w stanie zastosować trochę logiki Np. nie dla joe public do użytku.Czy cokolwiek innego musi być chronione, czy tylko samo hasło?

Jeśli tak, możesz zajrzeć na:

  • Użyj jednorazowa blokada / generator haseł (breloki RSA nie są tanie, a jeśli masz takie pieniądze do wydania, możesz pozwolić sobie na TLS)
  • Inne dwuetapowe uwierzytelnianie, takie jak SMS (nie bez własnych problemów).
  • Prosty mechanizm wyzwania / odpowiedzi służący do zaciemnienia hasła, na przykład strona wyświetla w tekście dwie cyfry (nie są też rażąco oznaczone), użytkownik musi rozpocząć hasło od proste obliczenia, takie jak różnica między dwiema liczbami dodanymi do każdej cyfry kodu PIN, być może z przypadkowymi elementami przed i / lub po, np. 98634572dkkgdld. Zmiana liczby wyzwań powinna zatrzymać powtarzanie ataków, które nie są podejmowane natychmiast, ale jeśli atakujący może przechwycić wystarczającą liczbę prób, może być w stanie to rozwiązać. Nie możesz też umieścić żadnej logiki zaciemniania w skrypcie skierowanym do użytkownika, ponieważ będzie to widoczne, a jeśli schemat będzie zbyt złożony, Twoi użytkownicy będą cię nienawidzić jeszcze bardziej.

Chciałbym nadal tak jest w przypadku TLS, certyfikaty są obecnie tanie (a nawet bezpłatne), więc zawiłe schematy zaciemniania naprawdę nie mają powodu, aby już istnieć.



To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 4.0, w ramach której jest rozpowszechniana.
Loading...