Hoe een wachtwoord veilig verzenden via HTTP?

Als de gebruiker op een inlogscherm een ​​formulier verzendt met zijn gebruikersnaam en wachtwoord, wordt het wachtwoord in platte tekst verzonden (zelfs met POST, corrigeer me als ik het mis heb).

Wat is de juiste manier om de gebruiker en zijn wachtwoord te beschermen tegen de derde partij die de communicatiegegevens zou kunnen afluisteren?

Ik ben me ervan bewust dat HTTPS een oplossing voor het probleem is, maar is er een manier om op zijn minst een bepaald beveiligingsniveau te garanderen met behulp van het standaard HTTP-protocol (POST-verzoek)? (misschien met behulp van javascript op de een of andere manier)

Waar ik het over had was een pagina – dat is een door PHP gegenereerde inlogpagina, die natuurlijk naar gebruikers wordt verzonden in een HTTP GET-verzoek als een HTML-bestand. Er is geen (@Jeremy Powel) verbinding tussen de server en de client, dus ik kan zo’n handshaking-protocol niet maken. En ik wil dat het volledige proces transparant is voor de gebruiker – hij wil een wachtwoord invoeren, niet omgaan met cryptografie.


Antwoord 1, autoriteit 100%

Het gebruik van HTTP met SSL zal uw leven veel gemakkelijker maken en u kunt gerust zijn. Zeer slimme mensen (in ieder geval slimmer dan ik!) hebben deze methode van vertrouwelijke communicatie jarenlang onder de loep genomen.


Antwoord 2, autoriteit 57%

Veilige authenticatie is een breed onderwerp. Kortom, zoals @jeremy-powell al zei, geef altijd de voorkeur aan het verzenden van inloggegevens via HTTPS in plaats van HTTP. Het zal veel kopzorgen met betrekking tot beveiliging wegnemen.

TSL/SSL-certificaten zijn tegenwoordig vrij goedkoop. Als u helemaal geen geld wilt uitgeven, is er zelfs een gratis letsencrypt.org– geautomatiseerde certificeringsinstantie.

Je kunt nog een stap verder gaan en caddyserver.comgebruiken die letsencrypt op de achtergrond aanroept.

Nu, zodra we HTTPS uit de weg hebben geruimd…

U moet geen login en wachtwoord verzenden via POST-payload of GET-parameters. Gebruik in plaats daarvan een Authorization header (Basic Access Authentication Scheme) die als volgt is opgebouwd:

  • De gebruikersnaam en het wachtwoord worden gecombineerd tot een tekenreeks, gescheiden door een
    dubbele punt, bijv.: gebruikersnaam:wachtwoord
  • De resulterende string is gecodeerd met
    de RFC2045-MIME-variant van Base64, behalve niet beperkt tot 76
    char/regel.
  • De autorisatiemethode en een spatie, d.w.z. “Basic” is dan
    geplaatst voor de gecodeerde tekenreeks.

bron: Wikipedia: Authorization header

Het lijkt misschien een beetje ingewikkeld, maar dat is het niet.
Er zijn tal van goede bibliotheken die deze functionaliteit direct voor u zullen bieden.

Er zijn een paar goede redenen waarom je een Authorization header zou moeten gebruiken

  1. Het is een standaard
  2. Het is eenvoudig (nadat je hebt geleerd hoe je ze moet gebruiken)
  3. Je kunt zo inloggen op URL-niveau: https://user:[email protected]/login(Chrome, bijvoorbeeld, converteert het automatisch naar Authorizationkoptekst)

BELANGRIJK:

  • Zoals @zaph in zijn opmerking hieronder aangeeft, is het geen goed idee om gevoelige informatie als GET-query te verzenden, omdat dit hoogstwaarschijnlijk in serverlogboeken terechtkomt.
  • De Authorizationheader-waarde is traditioneel een base64-gecodeerde gebruikersnaam/wachtwoord. Base64 is geen encryptie. De oorspronkelijke waarde kan worden verkregen door een on-path aangevallen met behulp van een eenvoudige base64-decode.


Antwoord 3, autoriteit 17%

U kunt een challenge-response-schema gebruiken. Stel dat de client en de server allebei een geheime S kennen. Dan kan de server er zeker van zijn dat de client het wachtwoord kent (zonder het weg te geven) door:

  1. Server stuurt een willekeurig getal, R, naar client.
  2. Client stuurt H(R,S) terug naar de server (waar H een cryptografische hashfunctie is, zoals SHA-256)
  3. Server berekent H(R,S) en vergelijkt deze met het antwoord van de client. Als ze overeenkomen, weet de server dat de client het wachtwoord kent.

Bewerken:

Er is hier een probleem met de frisheid van R en het feit dat HTTP staatloos is. Dit kan worden afgehandeld door de server een geheim te laten maken, bel het q, dat alleen de server kent . Dan gaat het protocol zo:

  1. Server genereert willekeurig nummer R. Het verzendt vervolgens naar de client H (R, Q) (die niet door de klant kan worden gesmeed).
  2. Client verzendt R, H (R, Q) en berekent H (R, S) en verzendt alles terug naar de server (waarbij H een cryptografische hash-functie is, zoals SHA-256)
  3. Server berekent H (R, S) en vergelijkt het met de reactie van de klant. Dan duurt het en berekent (opnieuw) H (R, Q). Als de versie van H (R, Q) en H (R, S) overeenkomt met de opnieuw-berekening van de server, vindt de server de klant geverifieerd.

Om op te merken, omdat H (R, Q) niet door de Klant kan worden gesmeed, werkt H (R, Q) als een cookie (en kan daarom als een cookie worden geïmplementeerd). < / strike>

een andere bewerking:

De vorige bewerking naar het protocol is onjuist als iedereen die H (R, Q) heeft waargenomen, het lijkt te kunnen afspelen met de juiste hash. De server moet onthouden welke R’s niet langer vers zijn. Ik ben CW’ing dit antwoord, zodat jullie hiermee kunnen bewerken en iets goeds goedmaken.


Antwoord 4, Autoriteit 15%

Als uw webhost het toestaat, of u moet met gevoelige gegevens omgaan, gebruik dan HTTPS, PERIODE. (Het is vaak vereist door de wet AFAIK).

anders als je iets wilt doen via http. Ik zou zoiets doen.

  1. De server houdt zijn openbare sleutel in op de inlogpagina.
  2. De client vult het inlogformulier in en klikt u op.
  3. Een AJAX-verzoek krijgt de huidige tijdstempel van de server.
  4. Client Side-script geeft aan de inloggegevens, de tijdstempel en een zout (hashed van analoge gegevens, bijvoorbeeld. muisbewegingen, sleutelpersevenementen), codeert het met behulp van de openbare sleutel.
  5. dient de resulterende hash in.
  6. server decodeert de hash
  7. Controleert of het tijdstempel recent genoeg is (hiermee alleen een kort 5-10 tweede venster). Verwerpt de aanmelding als het tijdstempel te oud is.
  8. slaat de hash gedurende 20 seconden op. Verwerpt dezelfde hash voor inloggen tijdens dit interval.
  9. verifieert de gebruiker.

Dus op deze manier is het wachtwoord beveiligd en kan dezelfde authenticatie niet opnieuw worden afgespeeld.

over de beveiliging van het sessietoken. Dat is een beetje moeilijker. Maar het is mogelijk om een ​​gestolen sessietoken een beetje harder te maken.

  1. De server stelt een extra sessiecookie in die een willekeurige reeks bevat.
  2. De browser verzendt deze cookie op het volgende verzoek.
  3. De server controleert de waarde in de cookie, als het anders is, dan vernietigt het de sessie, anders is alles in orde.
  4. De server stelt de cookie opnieuw in met verschillende tekst.

Dus als het sessie-token is gestolen, wordt een verzoek gestuurd door iemand anders, dan wordt op het volgende verzoek van de originele gebruiker de sessie vernietigd. Dus als de gebruiker actief doorbladert op de site, klikt u vaak op links, dan gaat de dief niet ver met het gestolen token. Deze regeling kan worden versterkt door een nieuwe verificatie te vereisen voor de gevoelige bewerkingen (zoals het verwijderen van account).

EDIT: Houd er rekening mee dat dit niet voorkomt dat MITM-aanvallen is als de aanvaller zijn eigen pagina opzet met een andere openbare sleutel en proxies-aanvragen aan de server.
Om hiertegen te beschermen, moet de publieke sleutel worden vastgemaakt in de lokale opslag van de browser of binnen de app om dit soort trucs te detecteren.

Over de implementatie: RSA is waarschijnlijk in het meest bekende algoritme, maar het is vrij traag voor lange sleutels. Ik weet niet hoe snel een PHP- of JavaScript-implementatie van zou zijn. Maar waarschijnlijk zijn er een snellere algoritmen.


Antwoord 5, Autoriteit 7%

Je kunt SRPgebruiken om veilige wachtwoorden te gebruiken via een onveilig kanaal. Het voordeel is dat zelfs als een aanvaller het verkeer opsnuift of de server compromitteert, hij de wachtwoorden niet op een andere server kan gebruiken. https://github.com/alax/jsrpis een javascript-bibliotheek die veilige wachtwoorden via HTTP in de browser of serverzijde (via node).


Antwoord 6, autoriteit 5%

Ik zou een server-side en client-side Diffie-Hellman sleuteluitwisselingssysteem gebruiken met AJAX of meerdere formulieren (ik raad het eerste aan), hoewel ik geen goede implementaties daarvan op internet zie. Onthoud dat een JS-bibliotheek altijd kan worden beschadigd of gewijzigd door MITM. Lokale opslag kan worden gebruikt om dit tot op zekere hoogte te bestrijden.


Antwoord 7

HTTPS is zo krachtig omdat het asymmetrische cryptografie gebruikt. Met dit type cryptografie kunt u niet alleen een gecodeerde tunnel maken, maar u kunt ook controleren of u met de juiste persoon praat en niet met een hacker.

Hier is de Java-broncode die het asymmetrische cijfer RSA (gebruikt door PGP) gebruikt om te communiceren:
http://www.hushmail.com/services/downloads/


Antwoord 8

u kunt ssl gebruiken voor uw host, er is een gratis project voor ssl zoals letsencrypt
https://letsencrypt.org/


Antwoord 9

Het gebruik van https klinkt hier het beste (certificaten zijn tegenwoordig niet zo duur). Als http echter een vereiste is, kunt u enige versleuteling gebruiken – versleutel het aan de serverzijde en ontcijfer het in de browser van de gebruiker (stuur de sleutel afzonderlijk).

We hebben dat gebruikt bij het implementeren van safevia.net– encryptie wordt gedaan aan de kant van de client (zender/ontvanger), dus gebruikersgegevens zijn niet beschikbaar op netwerk- of serverlaag.

Other episodes