Kriptimi në PHP. Enkriptoni, deshifroni të dhënat duke përdorur një çelës në PHP Enkriptimi dhe çelësat e vërtetimit

  • Përkthimi
  • Tutorial

Nga përkthyesi: në procesin e programimit, nuk harroj kurrë se jam rrezikshëm i paaftë në kriptografi dhe i këshilloj të gjithë të vazhdojnë nga kjo tezë (epo, ndoshta përveç jush dhe atij djalit të lezetshëm atje). Megjithatë, në një mënyrë apo tjetër, në procesin e punës lindin probleme që lidhen me mbrojtjen e të dhënave, të cilat duhet të zgjidhen. Prandaj, unë sjell në vëmendjen tuaj një përkthim të një artikulli nga zhvilluesi finlandez Timo H, të cilin e gjeta mjaft interesant dhe të dobishëm.

Ky është një udhëzues i shpejtë se si të shmangni grackat e zakonshme me kriptim simetrik në PHP.

Ne do të shqyrtojmë rastin kur të dhënat përpunohen në anën e serverit (në veçanti, kriptimi ndodh në server, dhe të dhënat mund të merren, për shembull, nga klienti në formën e tekstit të qartë, fjalëkalimit, etj.), që është një rast tipik për aplikacionet PHP.

Informacioni në këtë udhëzues nuk duhet të përdoret për të krijuar lidhje rrjeti të koduara që kanë kërkesa më komplekse. Për raste të tilla, duhet të përdorni spiun ose TLS.

Natyrisht, rekomandimet e dhëna këtu nuk janë "e vetmja mënyrë e mundshme" për të organizuar enkriptimin në PHP. Qëllimi i këtij udhëzuesi është të përpiqet të lërë më pak hapësirë ​​për gabime dhe vendime të vështira dhe të paqarta.

Funksionet e enkriptimit në PHP

Përdorni shtesat Mcrypt ose OpenSSL.

Algoritmi i kriptimit dhe mënyra e tij e funksionimit, kodi një herë (vektori i inicializimit)

Përdorni AES-256 në modalitetin CTR me një kod të rastësishëm një herë ( përafërsisht. përkthimi: nonce). AES është një standard, kështu që ju mund të përdorni funksionet e cilësdo prej shtesave - Mcrypt ose OpenSSL.

Gjeni gjithmonë një kod të ri një herë. Në këtë rast, duhet të përdorni një burim të sigurt kriptografik të numrave të rastit. Lexoni pak më shumë rreth gjenerimit të numrave të rastësishëm më poshtë. Kodi i njëhershëm nuk është sekret dhe mund të lidhet me tekstin e koduar për transmetim dhe deshifrim pasues.

Kodi i njëhershëm duhet të jetë 128 bit (16 byte), vetëm një varg bajtësh pa asnjë kodim.

Në shtrirjen Mcrypt, AES njihet si Rijndael-128 ( përafërsisht. përkth.: përkundër faktit se po flasim për AES-256, ky nuk është një gabim. AES-256 != Rijndael-256). Në OpenSSL, përkatësisht, AES-256-CTR.

Shembull i përdorimit të Mcrypt:
Shembull OpenSSL:
Verifikoni që enkriptimi po funksionon siç duhet duke përdorur vektorët e testimit ( përafërsisht. përkthimi: për AES-256-CTR shih paragrafin F.5.5 në faqen 57).

Për modalitetin CTR, ka disa kufizime në vëllimin total të të dhënave të koduara. Mund të mos e hasni këtë në praktikë, por mbani në mend se nuk duhet të kriptoni më shumë se 2^64 bajt të dhëna me një çelës, pavarësisht nëse është një mesazh i gjatë apo shumë i shkurtër.

Modaliteti CTR mbetet i qëndrueshëm vetëm nëse nuk përdorni të njëjtin kod një herë me të njëjtin çelës. Për këtë arsye, është e rëndësishme të gjenerohen kode një herë duke përdorur një burim të fortë kriptografik të rastësisë. Për më tepër, kjo do të thotë që nuk duhet të kriptoni më shumë se 2^64 mesazhe me një çelës të vetëm. Meqenëse gjatësia e kodit një herë është 128 bit, kufiri në numrin e mesazheve (dhe kodet e tyre përkatëse një herë) prej 2^128/2 është i rëndësishëm për shkak të Paradoksit të Ditëlindjes ( përafërsisht. përkthimi:).

Dhe mbani mend se kriptimi nuk do ta fshehë faktin se sa të dhëna po dërgoni. Si shembull i një rasti ekstrem, nëse enkriptoni mesazhe që përmbajnë vetëm "po" ose "jo", padyshim që enkriptimi nuk do ta fshehë atë informacion.

Autentifikimi i të dhënave

Kontrolloni gjithmonë autenticitetin dhe integritetin e të dhënave.
Për ta bërë këtë, përdorni MAC pas kriptimit. Ato. Së pari të dhënat kodohen dhe më pas merret HMAC-SHA-256 nga teksti i shifruar që rezulton, duke përfshirë vetë tekstin e koduar dhe kodin një herë.

Kur deshifroni, së pari kontrolloni HMAC duke përdorur një algoritëm krahasimi që është rezistent ndaj sulmeve të kohës. Mos krahasoni drejtpërdrejt $user_submitted_mac dhe $calculated_mac duke përdorur operatorët e krahasimit == ose ===. Është edhe më mirë të përdorni "kontrollin e dyfishtë HMAC".

Nëse kontrolli HMAC është i suksesshëm, deshifrimi mund të kryhet në mënyrë të sigurt. Nëse HMAC nuk është i përshtatshëm, mbylleni menjëherë.

Çelësat e kriptimit dhe vërtetimit

Idealisht, përdorni çelësat që rrjedhin nga një burim i fortë kriptografik i rastësisë. AES-256 kërkon 32 bajt të dhëna të rastësishme (një varg "i papërpunuar" - një sekuencë bitash pa përdorur asnjë kodim).

Nëse aplikacioni funksionon nën versionin PHP nën 5.5, i cili nuk ka një implementim të integruar të PBKDF2, atëherë do t'ju duhet të përdorni implementimin tuaj në PHP, një shembull i të cilit mund të gjendet këtu: https://defuse. ca/php-pbkdf2.htm. Kini parasysh se mbështetja në zbatimin tuaj mund të mos e zgjidhë siç duhet çelësin siç bën funksioni i integruar hash_pbkdf2().

Mos përdorni të njëjtin çelës për kriptim dhe vërtetim. Siç u tha më lart, 32 bajt kërkohen për çelësin e enkriptimit dhe 32 bajtë për çelësin e vërtetimit (HMAC). Me PBKDF2 ju mund të merrni 64 bajt nga fjalëkalimi dhe të përdorni, të themi, 32 bajtët e parë si çelës enkriptimi dhe 32 bajtët e mbetur për çelësin e vërtetimit.

Nëse fjalëkalimet tuaja ruhen në një skedar, për shembull, si një varg HEX, mos i rikodoni para se t'i futni në funksionet e enkriptimit. Në vend të kësaj, përdorni PBKDF2 për të kthyer çelësat e koduar me HEX direkt në një çelës kriptimi ose vërtetimi me cilësi të lartë. Ose përdorni SHA-256 pa dalje kodimi shtesë (vetëm një varg 32 bajt) për të hash fjalëkalimet. Përdorimi i hashimit të rregullt të fjalëkalimit siguron entropi të mjaftueshme. Më shumë detaje jepen në paragrafët e mëposhtëm.

Shtrirja e çelësit

Së pari, duhet të shmangni përdorimin e çelësave me entropi të ulët. Por prapëseprapë, nëse keni nevojë të përdorni, për shembull, fjalëkalime të përdoruesit, atëherë duhet patjetër të përdorni PBKDF2 me një numër të madh përsëritjesh për të maksimizuar sigurinë e çelësit.

Një nga parametrat e PBKDF2 është numri i përsëritjeve të hashimit. Dhe sa më i lartë të jetë, aq më e madhe është siguria e çelësit ku mund të mbështeteni. Nëse kodi juaj po ekzekutohet në një platformë 64-bitësh, përdorni SHA-512 si algoritmin hash për PBKDF2. Për një platformë 32-bit, përdorni SHA-256.

Megjithatë, nuk është e mundur të përdoret një numër relativisht i lartë përsëritjesh në aplikacionet online për shkak të rrezikut të një sulmi DoS. Prandaj, cilësia kryesore nuk do të jetë aq e lartë sa në aplikacionet offline, të cilat mund të përballojnë një numër të madh përsëritjesh pa një rrezik të tillë. Si rregull, për aplikacionet në internet, një numër i tillë i përsëritjeve hash zgjidhet në mënyrë që PBKDF2 të marrë jo më shumë se 100 ms.

Në rast se mund të përdorni fjalëkalime me entropi të lartë, nuk është e nevojshme ta zgjeroni atë siç do të bënit për fjalëkalimet me entropi të ulët. Për shembull, nëse krijoni një "encryption_master_key" dhe një "auth_master_key" duke përdorur /dev/urandom, atëherë nuk ka fare nevojë për PBKDF2. Vetëm sigurohuni që të përdorni çelësat si sekuenca bitash, pa asnjë kodim.

Për më tepër, me PBKDF2 nuk është e vështirë të merrni si çelësat e enkriptimit ashtu edhe të vërtetimit nga një fjalëkalim i vetëm kryesor (thjesht përdorni një numër të vogël përsëritjesh ose edhe një). Kjo është e dobishme nëse keni vetëm një "fjalëkalim kryesor" të përdorur si për kriptim ashtu edhe për vërtetim.

Ruajtja dhe menaxhimi i çelësave

Gjëja më e mirë është të përdorni një pajisje të veçantë të dedikuar për ruajtjen e çelësave (HSM).

Nëse kjo nuk është e mundur, atëherë për të komplikuar sulmin, mund të përdoret enkriptimi i skedarit të çelësit ose skedarit të konfigurimit (i cili ruan çelësat aktualë të enkriptimit/autentifikimit) duke përdorur një çelës të ruajtur në një vend të veçantë (jashtë drejtorisë kryesore ose rrënjës së faqes) . Për shembull, mund të përdorni një variabël mjedisi Apache në httpd.conf për të ruajtur çelësin e nevojshëm për të deshifruar skedarin aktual të çelësave:
SetEnv keyfile_key crypto_strong_high_entropy_key # Mund të përdorni këtë variabël në PHP duke përdorur $_SERVER["keyfile_key"] # Pjesa tjetër e konfigurimit
Tani, nëse skedarët në rrënjë të sajtit dhe më poshtë, duke përfshirë skedarët me çelësa, janë komprometuar (për shembull, nëse rrjedh një kopje rezervë), të dhënat e koduara do të mbeten të sigurta sepse çelësi i ruajtur në variablin e mjedisit nuk është komprometuar. Është e rëndësishme të mbani mend se skedarët httpd.conf duhet të kopjohen veçmas dhe të mos kompromentohet ndryshorja keyfile_key përmes, për shembull, daljes së phpinfo().

Nëse përdorni një skedar në vend të një parametri konfigurimi, është e mundur të organizoni rrotullimin e tastit. Në rastin më të keq, nëse një kundërshtar ka marrë çelësat tuaj të enkriptimit dhe vërtetimit pa u vënë re, atëherë rrotullimi i çelësave në disa intervale mund të kufizojë aksesin e tyre (duke supozuar se nuk mund të marrin çelësa të rinj). Kjo teknikë do të ndihmojë në uljen e dëmit sepse armiku nuk do të jetë në gjendje të përdorë çelësat e komprometuar pafundësisht.

Kompresimi i të dhënave

Në përgjithësi, nuk duhet ta kompresoni tekstin burimor përpara se ta kriptoni. Kjo mund t'i japë armikut një mjet shtesë për analizë.

Për shembull, nëse ruani të dhënat e sesionit në cookie të koduara, disa prej të cilave janë dhënë nga përdoruesi dhe disa përfaqësojnë informacion sekret, një kundërshtar mund të mësojë informacion shtesë rreth sekretit duke dërguar, si një përdorues i zakonshëm, disa të dhëna të krijuara posaçërisht dhe duke matur se si ndryshon gjatësia e teksteve të shifruara që rezultojnë.

Teksti kompresohet në mënyrë më efikase nëse ka zona të përsëritura. Duke manipuluar të dhënat e përdoruesit, mund t'i zgjidhni ato në mënyrë që pjesërisht të përkojnë me të dhënat sekrete. Sa më e madhe të jetë përputhja, aq më i vogël është teksti shifror i daljes. Ky lloj sulmi quhet KRIM.

Nëse nuk keni nevojë të vështirë për të kompresuar të dhënat, mos i kompresoni ato.

Mjedisi i serverit

Si rregull i përgjithshëm, nuk duhet të strehoni aplikacione të ndjeshme ndaj sigurisë në një server të përbashkët. Për shembull, në pritjen e përbashkët, ku një kundërshtar mund të hyjë në një makinë virtuale në të njëjtin server fizik si ju.

Ka arsye të ndryshme që i bëjnë serverët e përbashkët një vend të dyshimtë për të pritur aplikacione kritike për sigurinë. Për shembull, sulmet ndërmjet serverëve virtualë janë demonstruar kohët e fundit: eprint.iacr.org/2014/248.pdf. Ky është një kujtesë e mirë që teknikat sulmuese nuk degradojnë, por përkundrazi janë të mprehta dhe përmirësuara me kalimin e kohës. Të tilla gracka duhet të merren gjithmonë parasysh.

Konsultimi i ekspertit

E fundit, por jo më pak e rëndësishme, konsultohuni me një ekspert për të rishikuar kodin tuaj të sigurisë.

(PHP 4, PHP 5, PHP 7)

crypt - Hashimi i vargut me një drejtim

Paralajmërim

Ky funksion nuk është (ende) binar i sigurt!

Përshkrim

kriptë (varg $str [, varg $kripë]): varg

kript () do të kthejë një varg hash duke përdorur algoritmin standard të bazuar në Unix DES ose algoritme alternative që mund të jenë të disponueshme në sistem.

Parametri i kripës është opsional. Megjithatë, kript () krijon një hash të dobët pa kripë. PHP 5.6 ose më vonë ngre një gabim E_NOTICE pa të. Sigurohuni që të specifikoni një kripë mjaft të fortë për siguri më të mirë.

fjalëkalimi_hash() përdor një hash të fortë, gjeneron një kripë të fortë dhe aplikon raundet e duhura automatikisht. fjalëkalimi_hash()është një e thjeshtë kript () mbështjellës dhe i pajtueshëm me hash-et ekzistuese të fjalëkalimit. Përdorimi i fjalëkalimi_hash() inkurajohet.

Disa sisteme operative mbështesin më shumë se një lloj hash. Në fakt, ndonjëherë algoritmi standard i bazuar në DES zëvendësohet nga një algoritëm i bazuar në MD5. Lloji hash shkaktohet nga argumenti salt. Përpara 5.3, PHP do të përcaktonte algoritmet e disponueshme në kohën e instalimit bazuar në cryptin e sistemit (). Nëse nuk ofrohet kripë, PHP do të gjenerojë automatikisht ose një kripë standarde me dy karaktere (DES) ose një dymbëdhjetë karaktere ( MD5), në varësi të disponueshmërisë së MD5 crypt() PHP vendos një konstante të emërtuar CRYPT_SALT_LENGTH që tregon kripën më të gjatë të vlefshme të lejuar nga hashët e disponueshëm.

Standardi i bazuar në DES kript () kthen kripën si dy karakteret e para të daljes. Gjithashtu përdor vetëm tetë karakteret e para të str , kështu që vargjet më të gjata që fillojnë me të njëjtat tetë karaktere do të gjenerojnë të njëjtin rezultat (kur përdoret e njëjta kripë).

Në sistemet ku funksioni crypt() mbështet lloje të shumta hash, konstantet e mëposhtme vendosen në 0 ose 1 në varësi të faktit nëse lloji i dhënë është i disponueshëm:

  • CRYPT_STD_DES- Hash standard i bazuar në DES me një kripë me dy karaktere nga alfabeti "./0-9A-Za-z". Përdorimi i karaktereve të pavlefshme në salt do të bëjë që crypt() të dështojë.
  • CRYPT_EXT_DES- Hash i zgjeruar i bazuar në DES. "Kripë" është një varg me 9 karaktere që përbëhet nga një nënvizim i ndjekur nga 4 bajt numërim përsëritjeje dhe 4 bajtë kripë. Këto janë të koduara si karaktere të printueshme, 6 bit për karakter, së pari karakteri më pak i rëndësishëm. Vlerat nga 0 deri në 63 janë të koduara si "./0-9A-Za-z". Përdorimi i karaktereve të pavlefshme në salt do të bëjë që crypt() të dështojë.
  • CRYPT_MD5- MD5 hashing me një kripë dymbëdhjetë karakteresh duke filluar me $1$
  • CRYPT_BLOWFISH- Blowfish hash me një kripë si më poshtë: "$2a$", "$2x$" ose "$2y$", një parametër kostoje me dy shifra, "$" dhe 22 karaktere nga alfabeti "./0-9A- Za-z”. Përdorimi i karaktereve jashtë këtij diapazoni në salt do të bëjë që crypt() të kthejë një varg me gjatësi zero. Parametri i kostos me dy shifra është logaritmi bazë-2 i numërimit të përsëritjeve për algoritmetrin bazë të hashimit të bazuar në Blowfish dhe duhet të jetë në intervalin 04-31, vlerat jashtë këtij diapazoni do të bëjnë që crypt() të dështojë. Versionet e PHP para 5.3.7 mbështesin vetëm "$2a$" si prefiks kripë: PHP 5.3.7 prezantoi prefikset e reja për të rregulluar një dobësi sigurie në zbatimin e Blowfish. Ju lutemi referojuni për detaje të plota të rregullimit të sigurisë, por për ta përmbledhur, zhvilluesit që synojnë vetëm PHP 5.3.7 dhe më vonë duhet të përdorin "$2y$" në preferencë ndaj "$2a$".
  • CRYPT_SHA256- SHA-256 hash me një kripë gjashtëmbëdhjetë karakteresh të prefiksuar me $5$. Nëse vargu i kripës fillon me "rounds=
  • CRYPT_SHA512- SHA-512 hash me një kripë gjashtëmbëdhjetë karakteresh të prefiksuar me $6$. Nëse vargu i kripës fillon me "rounds= $", vlera numerike e N përdoret për të treguar se sa herë duhet të ekzekutohet cikli hashing, njëlloj si parametri i kostos në Blowfish. Numri i paracaktuar i raundeve është 5000, ka një minimum prej 1000 dhe një maksimum prej 999,999,999. Çdo përzgjedhje e N jashtë këtij diapazoni do të shkurtohet në kufirin më të afërt.

Që nga PHP 5.3.0, PHP përmban zbatimin e vet dhe do ta përdorë atë nëse sistemit i mungon mbështetja për një ose më shumë nga algoritmet.

Parametrat

Vargu që do të hash.

Kujdes

Duke perdorur CRYPT_BLOWFISH algoritmi, do të rezultojë që parametri str të shkurtohet në një gjatësi maksimale prej 72 karakteresh.

Një varg kripe opsionale për ta bazuar hashimin. Nëse nuk ofrohet, sjellja përcaktohet nga zbatimi i algoritmit dhe mund të çojë në rezultate të papritura.

Vlerat e Kthimit

Kthen vargun e hashuar ose një varg që është më i shkurtër se 13 karaktere dhe është i garantuar të ndryshojë nga kripa në rast dështimi.

Paralajmërim

Kur vërtetohen fjalëkalimet, duhet të përdoret një funksion i krahasimit të vargjeve që nuk është i cenueshëm ndaj sulmeve të kohës për të krahasuar rezultatin e kript () ndaj hash-it të njohur më parë. PHP 5.6 e tutje ofron hash_equals() për këtë qëllim.

Ndryshim

Version Përshkrim
5.6.5 Kur vargu i dështimit "*0" jepet si kripë, "*1" tani do të kthehet për konsistencë me implementimet e tjera të kriptave. Përpara këtij versioni, PHP 5.6 do të kthente gabimisht një hash DES.
5.6.0 Ngrini paralajmërimin e sigurisë E_NOTICE nëse kripa është hequr.
5.5.21 Kur vargu i dështimit "*0" jepet si kripë, "*1" tani do të kthehet për konsistencë me implementimet e tjera të kriptave. Përpara këtij versioni, PHP 5.5 (dhe degët e mëparshme) do të kthenin gabimisht një hash DES.
5.3.7 Shtuar $2x$ dhe $ 2 y $ Modalitetet Blowfish për t'u marrë me sulmet e mundshme me bit të lartë.
5.3.2 U shtua kripta SHA-256 dhe SHA-512 bazuar në zbatimin e Ulrich Drepper.
5.3.2 Rregulloi sjelljen e Blowfish në raunde të pavlefshme për të kthyer vargun "dështim" ("*0" ose "*1"), në vend që të kthehej në DES.
5.3.0 PHP tani përmban zbatimin e vet për algoritmet MD5 crypt, Standard DES, Extended DES dhe Blowfish dhe do ta përdorë atë nëse sistemit i mungon mbështetja për një ose më shumë nga algoritmet.

Shembuj

Shembulli #1 kript () shembuj

$hashed_password = crypt("mypassword"); // le të krijohet automatikisht kripa

/* Ju duhet të kaloni të gjitha rezultatet e crypt() si kripë për krahasimin e a
fjalëkalimin, për të shmangur problemet kur përdoren algoritme të ndryshme hashimi. (Siç
thuhet më sipër, hashimi standard i fjalëkalimit të bazuar në DES përdor një kripë me 2 karaktere,
por hashimi i bazuar në MD5 përdor 12.) */
if (hash_equals ($hashed_password, crypt ($user_input, $hashed_password))) (
echo "Fjalëkalimi u verifikua!" ;
}
?>

Shembulli #2 Duke përdorur kript () me htpasswd

// Vendosni fjalëkalimin
$password = "mypassword" ;

// Merrni hash-in, duke e lënë kripën të gjenerohet automatikisht
$hash = crypt ($fjalëkalim);
?>

Shembulli #3 Duke përdorur kript () me lloje të ndryshme hash

/* Këto kripëra janë vetëm shembuj dhe nuk duhet të përdoren fjalë për fjalë në kodin tuaj.
Ju duhet të krijoni një kripë të veçantë, të formatuar saktë për çdo fjalëkalim.
*/
nëse (CRYPT_STD_DES == 1 ) (
echo "Standard DES: " . crypt ("rasmuslerdorf", "rl"). "\n" ;
}

nëse (CRYPT_EXT_DES == 1 ) (
echo "Extended DES: " . crypt ("rasmuslerdorf", "_J9..rasm"). "\n" ;
}

nëse (CRYPT_MD5 == 1 ) (
jehonë "MD5: " . crypt ("rasmuslerdorf", "$1$rasmusle$"). "\n" ;
}

nëse (CRYPT_BLOWFISH == 1 ) (
jehonë "Blowfish: " . crypt("rasmuslerdorf" , "$2a$07$usesomesillystringforsalt$") . "\n" ;
}

nëse (CRYPT_SHA256 == 1 ) (
jehona "SHA-256: " . crypt("rasmuslerdorf" , "$5$rounds=5000$usesomesillystringforsalt$") . "\n" ;
}

nëse (CRYPT_SHA512 == 1 ) (
jehonë "SHA-512: " . crypt("rasmuslerdorf" , "$6$rounds=5000$usesomesillystringforsalt$") . "\n" ;
}
?>

Çdo informacion mund të kodohet ose deshifrohet, duke përfshirë përdorimin e PHP. Kjo gjuhë ka shumë aftësi të enkriptimit të të dhënave, nga e thjeshta në komplekse.

Le të shohim metodat bazë të kriptimit

bazë64- ju lejon të kriptoni dhe deshifroni të dhënat duke përdorur algoritmin MIME base64. Nuk përdor çelësa dhe shpesh përdoret për të fshehur lidhjet në PHP.

Shembuj:
//kriptoni tekstin
$text = "Lidhje";
echo base64_encode ($text); //Prodhon: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==
//deshifrimi
echo base64_decode("PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==");
?>

Siç mund ta shihni, ne fillimisht përdorëm operacionin base64_encode dhe morëm shifrën: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==, dhe më pas e zëvendësoi atë në base64_decode dhe mori përsëri lidhjen.

md5- ju lejon të hash të dhënat në mënyrë të njëanshme. Kjo do të thotë, ndryshe nga base64, ju nuk do të jeni më në gjendje t'i deshifroni ato përsëri. Shpesh md5 përdoret për të ruajtur fjalëkalimet në një bazë të dhënash, por kohët e fundit kombinimi i koduar md5 është bërë i lehtë për t'u gjetur në tabelat e deshifrimit, të ofruar me dashamirësi nga shumë sajte dhe algoritme. Prandaj, për të ruajtur fjalëkalimet md5, është më mirë të zëvendësoni algoritmet me Blowfish.

Shembull:

//kriptoni tekstin
echo md5 ("kombinim");
?>

Kriptimi i çelësit

Dhe shembulli i fundit i enkriptimit/deshifrimit për të cilin doja të flisja përdor një çelës (si fjalëkalim). Kjo do të thotë, ju kaloni një çelës unik në funksionin e kriptimit dhe kodi kodohet së bashku me të. Për të deshifruar, duhet t'i jepni funksionit kodin e koduar dhe një çelës që vetëm ju e dini. Një shembull i përdorimit të funksioneve në fund të kodit.

funksioni __encode ($text, $key) (



$enc_text=base64_encode(mcrypt_generic($td,$iv.$tekst));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
kthej $enc_text; ) )
funksioni strToHex ($string) (
$hex="";
për ($i=0; $i< strlen($string); $i++) { $hex .= dechex(ord($string[$i])); }
kthej $hex; )
funksioni __dekodimi ($text, $key) (
$td = mcrypt_module_open("tripledes", "", "cfb", "");
$iv_size = mcrypt_enc_get_iv_size($td);
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
nëse (mcrypt_generic_init ($td, $key, $iv) != -1) (
$decode_text = substr(mdecrypt_generic($td, base64_decode($tekst)),$iv_size);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
kthej $decode_text; ) )
funksioni hexToStr($hex) (
$string="";
për ($i=0; $i< strlen($hex)-1; $i+=2) { $string .= chr(hexdec($hex[$i].$hex[$i+1])); }
ktheje $string; )

$str = "Buns që duhet të kodohen!
Me çelës";
$code = strToHex(__encode($str, "My#key-do-36-simvolov"));
echo "Kodi i koduar: ".$code."
";

$str = __dekodi(hexToStr($code), "My#key-do-36-simvolov");
echo "Kodi i deshifruar: ".$str."
";
?>

Ju mund të enkriptoni përmbajtjen html. Gjatësia e çelësit duhet të jetë jo më shumë se 36 karaktere.

Kjo metodë mund të përdoret për të enkriptuar disa të dhëna dhe për t'i vendosur ato në një skedar txt ose bazë të dhënash dhe për t'i marrë ato duke përdorur deshifrimin me një çelës.

Natyrisht, çdo kod mund të deshifrohet/hakohet dhe ky nuk bën përjashtim, ndaj përdorni metoda të forta enkriptimi.

Një nga të vërtetat themelore të kriptografisë është se nuk duhet të shpikni asgjë në këtë fushë nëse nuk jeni profesionist. Kjo është pjesërisht e vërtetë, sepse të gjitha më të mirat janë shpikur, vuajtur dhe përdorur prej dekadash në fushën e teknologjisë së informacionit. Ana tjetër e së vërtetës është se zhvillimi i një fushe të caktuar njohurish ndodh vetëm me një fluks të vazhdueshëm idesh të freskëta dhe zgjidhjesh origjinale në të.

Për arsye të dukshme, ne nuk do të synojmë gjigantët e kriptografisë industriale si AES, por do të zhytemi, si të thuash, në kërkimin tonë kriptografik me blackjack dhe gëzim.

Pjesërisht sepse është interesante, pjesërisht sepse duke modeluar diçka tuajën dhe duke e krahasuar me standardet e njohura, ju shihni qartë kontrastin, zgjidhjet efektive dhe lëshimet e drejtpërdrejta dhe kuptoni se çfarë mund të përpiqeni për të përmirësuar efikasitetin.

Por tashmë mjaft ujë.

Le të themi se aplikacioni ynë në internet është i shkruar në PHP, ka nevojë për enkriptim të kthyeshëm dhe ne besojmë se mund të shkruajmë sistemin tonë të shifrimit.

Pra, le të shkruajmë sistemin tonë të kthyeshëm të enkriptimit me çelësa privatë dhe publikë, një që do të ketë veçoritë e mëposhtme të një algoritmi kriptografik pak a shumë të sigurt:

  1. Prania e simboleve të zhurmës në shifrën përfundimtare.
  2. Informacioni në çdo kanal dërgues-destinacion do të kodohet duke përdorur një çelës privat dhe funksioni i përputhjes do të jetë unik për secilin çelës.
  3. Çdo mesazh do të marrë një kod përmbledhës - një kod unik që është një funksion i çelësit privat dhe mesazhit origjinal. Kjo kërkohet për të arritur unike të funksionit të përputhjes "simbol burimi".<=>simbol i koduar” jo vetëm për kanalin “Dërguesi-Marrës”, por edhe për çdo mesazh individual.

    Kështu, edhe nëse imagjinojmë që korrespondenca e simboleve të koduara dhe origjinale për një mesazh të caktuar është bërë e njohur përmes përdorimit të analizës kriptografike, për shembull, analizës së frekuencës, kjo nuk jep asnjë preferencë kur studion një mesazh tjetër.

  4. Për të komplikuar analizën e frekuencës, ne do të kodojmë çdo simbol të mesazhit fillestar me dy simbole shifrore.
Pra, çfarë ndodhi.

Në fakt, ju mund të shihni rezultatin përfundimtar

Klasa SymCoder përfshin metoda të enkriptimit dhe deshifrimit.

Kriptimi kryhet me metodën code(), e cila merr mesazhin origjinal si hyrje.

Këtu, një mesazh nga tabela e korrespondencës së gjeneruar në tab_coded krijon një mesazh të koduar, të holluar përgjatë skajeve dhe brenda me simbolet e zhurmës.

Nga rruga, simbolet e zhurmës janë unike për çdo kanal të destinacionit të dërguesit, pasi ato krijohen duke përdorur çelësin e kanalit, por nuk janë unike për mesazhet. Simbolet e përdorura për enkriptim në kodet_simbolet janë disa shenja pikësimi dhe simbole si %, @, etj.

Për çdo simbol të koduar, ka dy simbole nga kodi_simbolet, për arsye të dukshme se ka disa herë më pak prej tyre se simbolet e koduara.

Tabela e korrespondencës me kodin "cre_tab_coded" është ndërtuar duke përdorur një përkthim të hash-it të çelësit të mesazhit në një grup me numrin e elementeve të barabartë me numrin e elementeve në grupin e simboleve të kodit. Pozicioni fillestar për kalimin e kodeve me dy karaktere është gjithashtu gjithmonë i ndryshëm dhe shoqërohet me çelësin e kanalit. Kjo bën të mundur që të sigurohemi që algoritmi për kalimin e simboleve të koduara dhe përputhjen e simboleve të kodit me to do të jetë gjithmonë i ndryshëm (ose është i garantuar shpesh).

Për shembull, mesazhi "përshëndetje botë", kur është i koduar, duket si ky:

Digest-a00bf11d-&?==&!&?.@.@=!=-.?&1.#&?=:.:.1%!&-%@&@%~&1^#=?%% .!%+.?.~=?..&?%&&:%~.#%@&1&1.#=?.#.?.!&1==&=.-=!

Dhe këtu është i njëjti mesazh, i koduar përsëri:

Digest-a00bf11d-=:.?=:&!.?.1&-=:=?.?.=.?.!&=%!=-%@=!%~.=^#.1%%. !%+=:.~.@..==%&&1%~.1%@=?.@.!&=.!&@=:&1.==:=!.1&:

Mund të shihet se përmbledhja e të njëjtit mesazh është e njëjtë, por shifra bëhet e ndryshme - simbolet e zhurmës shtohen në një përputhje arbitrare dhe në një renditje arbitrare për çdo kriptim të ri.

Mesazhet kanë tepricë, e cila zvogëlohet me rritjen e vëllimit të mesazhit, deri në 10% zhurmë (për mesazhet më të shkurtra, zhurma arrin 90% ose përqindje më e lartë), gjatësia minimale e një mesazhi të koduar është 116 karaktere. Një nga disavantazhet e kësaj metode të kriptimit është se mesazhet e koduara të paktën dyfishohen.

Dekodimi konsiston në përkthimin e kundërt të formës "simbol i kodit" - simboli origjinal me zhurmë të shkëputur nga mesazhi. Cili mund të jetë çelësi? Në thelb, çdo varg që është unik për çdo palë destinacion-marrës.

Për shembull, nëse po krijoni një mesazher me enkriptim mesazhesh, atëherë versioni më i thjeshtë i çelësit privat mund të jetë md5($user_id_1. $salt. $user_id_2), atëherë çelësi do të jetë unik për çdo kanal mesazhi.

Le të themi se ju duhet të shkëmbeni të dhëna midis dy serverëve. Për të mbrojtur të dhënat nga trafiku i përgjimit, të dhënat janë të koduara. Epo, për shembull, transferimi i veprimeve brenda një botnet. Kjo është ajo që në thelb nuk është enkriptim, por quhet kodim, dhe funksionet e njohura përdoren për të deshifruar një kod të tillë.

Si një shembull tjetër i pseudo-kriptimit, unë do të jap një shembull të "kriptimit" të fjalëkalimeve në bazën e të dhënave të një CMS - atje fjalëkalimet nuk janë të koduara në md5 () ose , por thjesht kodohen përmes bazës64. Ato. Kur baza e të dhënave zbulohet, nuk do të jetë e vështirë për një haker të dekriptojë të gjitha fjalëkalimet duke përdorur funksionin e integruar PHP base64_decode().

Ne duhet të transmetojmë të dhëna pa u shqetësuar se dikush do të jetë në gjendje të përgjojë tekstin dhe ta deshifrojë atë. PHP ka një paketë të njohur të enkriptimit të të dhënave të quajtur Mcrypt, e cila ofron kriptim të dyanshëm (d.m.th., kriptimi dhe deshifrimi aktual i të dhënave).

Versioni 2.4.7 i Mcrypt mbështet algoritmet e mëposhtme të kriptimit simetrik: Blowfish, RC2, Safer-sk64 xtea, Cast-256, RC4, Safer-sk128, DES, RC4-iv, Serpent, Enigma, Rijndael-128, Threeway, Rijndael-1 , TripleDES, LOKI97, Rijndael-256, Twofish, Panama, Saferplus, etj. Më shumë detaje për secilin algoritëm janë shkruar në Wikipedia.

Meqenëse përdoret enkriptimi simetrik, çelësi duhet të jetë i njohur për të dyja palët dhe të mbahet i fshehtë.

Shembull i enkriptimit dhe deshifrimit të një vargu

mcrypt_module_open("des", "", "ecb", "")
Ky funksion hap modulin e algoritmit dhe mënyrën e përdorur. Për këtë shembull, algoritmi DES është në modalitetin ECB.

$key = substr($key, 0, mcrypt_enc_get_key_size($td));
Madhësia maksimale e çelësit duhet të merret duke thirrur funksionin mcrypt_enc_get_key_size() dhe çdo vlerë më e vogël se kjo do të jetë e saktë.

$s = mcrypt_generic ($td, $burimi);
Kur kriptoni, të dhënat mbushen me zero bajt për të siguruar që të dhënat të jenë të gjata n*blloqe. Madhësia e bllokut përcaktohet nga algoritmi (për DES madhësia e bllokut është 64 bit). Prandaj, kur deshifroni, "\0" mund të shfaqet në fund të rreshtit, i cili hiqet nga funksioni trim()