Digest autentificare în PHP
Restricționarea accesului la anumite zone ale site-ul arată de obicei
monoton: fiecare utilizator este dat un nume de utilizator și parolă, sau el
ei aleg, și să intre în partea protejată a site-ului care au nevoie pentru a intra. Din punct de vedere tehnic pentru a verifica parola utilizată
diferite metode. HTML formular poate fi folosit pentru a introduce numele de utilizator și parola.
În acest caz, parola este trimis la server în text clar în POST-cerere.
Acest lucru nu este acceptabil în cazul în care utilizatorul este așezat în LAN, acolo unde este posibil
utilizarea sniffer. Pentru a rezolva această problemă, o metodă inventată
autentificarea prin utilizarea în care hashes parola nu este trimis, și
în funcție hash șir de caractere transmis pe o parolă, unele de unică folosință
parametru, și, eventual, chiar și de către orice parametri. Această metodă este încă
numita provocare / răspuns, ca atunci când se utilizează clientul
primește o solicitare de la un parametru de unică folosință și trimite un răspuns care conține un hash. La nivelul HTTP 1.1 este posibilă metodă de autentificare
De bază, că nici o mai bună utilizare a HTML-forme, și Digest, care
ne aruncăm o privire mai atentă.
Digest vs Basic
AuthType Digest
AuthUserFile <файл>
AuthName <название защищаемой области>
necesită valid_user
Complet descrie metoda poate fi găsită în RFC 2069, și dacă
Pe scurt, metoda funcționează bine. Când serverul primește o cerere referitoare la o zonă protejată,
401 se produce o eroare de autorizare antet necesare și solicitare
Autentificarea ca aceasta:
WWW-autentificaþi: Digest = tărâm »securizat zona», nOdată = »123456123456"
domeniu - este numele zonei protejate, iar nonce - un one-off
valoare. Există parametri opționali pe care le vom discuta
nu va fi. Clientul repetă solicitarea prin adăugarea unui antet cum ar fi următoarele:
Autorizare: Digest domeniu = »zonă sigură», numele de utilizator = »123" , uri =» / index.php », nOdată =» 123 456 123 456" , ca răspuns = »1234567890abcdef1234567890abcdef»
Uri parametru trebuie să se potrivească cu URI-ul în cerere și răspuns - l
răspuns, care se calculează după cum urmează:
răspuns = H (H (A1) + «:» + nonce + «:» + H (A2))
H - funcție hash MD5-default
A1 = utilizator + «:» + + tărâm «:» + parola
A2 = Metoda de cerere + «:» + URI
Metoda de cerere - un GET, POST, și așa mai departe.
După cum puteți vedea, A1 nu depinde nici de cerere sau de unică folosință
valori, astfel încât serverul poate fi stocată parola,
H (A1). Asta e modul în care aceasta este pusă în aplicare în mod_digest în Apache.
Cu toate acestea, aceleași date sunt suficiente și client. Un atacator, având
Acest hash poate da seama răspunsul pentru formulele de mai sus și
formează un HTTP-cerere, de exemplu, folosind programul
AccessDriver și instrumentul său HTTP
Debugger. Mai mult, acest proces este prezentat mai jos. Serverul trebuie să verifice dacă nonce
cei care au fost emise anterior pentru client și dacă acesta este de actualitate.
În cazul în care răspunsul corespunde nonce, dar valoarea acestui parametru
nu este relevant, având în vedere mai sus de răspuns 401, cu singura
cu excepția faptului că în antetul WWW-Authenticate este adăugat la parametrul
stătut = true, ceea ce indică faptul că accesul este refuzat pentru acest motiv,
și ar trebui să încercați din nou, fără a solicita utilizatorului o parolă nouă. Acest lucru, IMHO, este incomod, pentru că în cazul în care o astfel de situație apare
la POST sau cererea cu un bloc mare de date PUT, atunci clientul va trebui să
transfera toate datele de două ori. Pentru a evita acest lucru, standardul oferit
antet de autentificare-Info, în care serverul poate răspunde atunci când
cerere de succes pentru a informa următoarea valoare o singură dată clientul.
Sintaxa este aceeași ca și în WWW-autentifice, cu excepția faptului că nonce
înlocuit cu nextnonce. Cu toate acestea, judecând după rezultatele mele
experimente, Opera ignoră acest antet. O altă soluție, în conformitate cu
RFC 2068 (HTTP / 1.1), serverul poate răspunde înainte de depunerea cererii de capăt,
pentru a reduce datele inutile ale clienților, dar este Apache + PHP
Nu poate fi realizat, deoarece script-ul începe să curgă numai după
ca Apache primesc pe deplin și analiza solicitarea.
Stocarea datelor între cereri
Acest script verifică doar parola, și funcționează în mod independent de
conectare. În funcție de succesul testului sunt date răspunsuri simple.
$ Realm = 'zonă sigură'; // Numele ariei protejate
$ Pass = 'trecere'; // Parola
$ Fileprefix = './'; // Calea către fișierul markerii care indică validitatea nonce
// obține titluri
$ Cap = apache_request_headers ();
// pavilion pe care le vom stabili la TRUE după verificarea cu succes
$ Auth_success = FALSE;
$ = Stale «»;
// Dacă nu antet Autorizare, și nu este nimic pentru a verifica
if (isset ($ antete [ 'Autorizare']))
$ Autorizare = $ antete [ 'Autorizare'];
/ * Antet Analizează folosind expresii regulate. Antetul conține cuvântul «Digest» și o listă de
tip paremetrov param = „valoare“ sau param = valoare, separate prin virgulă. Această expresie regulată se potrivește cu un astfel de parametru. * /
preg_match_all ( „/ (, | \ s | ^) (\ w +) = («([^»] *)» | ([\ w \ d] *)) (, | $) /“,
$ Autorizarea, meciuri $, PREG_SET_ORDER);
/ * Acum crea confort pentru mai multe matrice de procesare în cazul în care cheile - numele parametrilor și valorile elementelor din matrice -
valorile parametrilor. * /
$ Auth_params = Array ();
pentru ($ i = 0; $ i
/ * Numele este întotdeauna în al doilea grup de paranteze, în sensul în funcție de faptul dacă citat sau nu, poate
fie în grupa a 4-a sau a 5. Pentru grupurile de paranteze căzute
în ramura nerealizat în matrice șir gol,
astfel încât să puteți adăuga pur și simplu valorile. * /
$ Auth_params [$ meci [2]] = $ meci [4]. $ Match [5];
>
/ * Se calculează răspunsul care corespunde
de conectare de intrare de utilizator, parola și parametrul nostru o singură dată a trecut la utilizator.
* /
$ A1 = $ auth_params [ 'username']. ':'. $ Auth_params [ 'domeniul']. ':'. $ Pass;
$ A2 = $ _SERVER [ 'REQUEST_METHOD']. ':'. $ _SERVER [ 'REQUEST_URI'];
$ Resp = md5 (md5 ($ a1) ':' $ auth_params [ 'nonce'] ':' md5 ($ a2) ....);
// Verificați răspunsul.
în cazul în care ($, respectiv == $ auth_params [ 'răspuns'])
// Verificați relevanța singur parametru
$ Fn = $ fileprefix. $ Auth_params [ 'nOdată'];
în cazul în care (@file_get_contents ($ fn) == $ _SERVER [ 'REMOTE_ADDR'])
deconectez ($ fn); // Mai multe această setare este irelevant
$ Auth_success = TRUE; // este autentificat
> altceva
// setarea One-time este irelevant
$ Stale = «stătut = true»;
>
>
>
în cazul în care ($ auth_success)
Print ( «
„);Print ( «autentificat cu succes \ n»);
var_dump ($ auth_params);> altceva
file_put_contents ($ fileprefix $ nonce, $ _SERVER [ 'REMOTE_ADDR'].);$ Proto = $ _SERVER [ 'SERVER_PROTOCOL'];
Antet ( «$ 401 Proto Nu a fost autorizat»);
Antet ( «WWW-autentificaþi: Digest domeniu = \» $ tărâm \ », nOdată = \» $ nOdată \ »$ stătut»);Print ( «
test de autorizare Digest „);„);
Print ( «Trebuie sa se autentifice cu metoda Digest»);
Print ( «
>Pasaj Digest Auth cu H cunoscut (A1)
Deschideți consola, du-te la folderul cu PHP și încercarea de a conduce următoarea comandă:
Digest- obține răspunsul dorit: c6d0af0db239d75c
3f59640a4896d096
Acum, a pus un verifica AccessDriver «antet date», care a apărut în copie
antete de teren care au fost trimise ultima interogare și le adaugă
Autorizare. Iată ce se întâmplă:Faceți clic pe «Conectare». Obținem rezultatul:
Arată acest articol unui prieten: