Šifrovanje u PHP-u. Šifriranje, dešifriranje podataka pomoću ključa u PHP ključevima za šifriranje i autentifikaciju

  • Prevod
  • Tutorial

Od prevodioca: u procesu programiranja nikad ne zaboravljam da sam opasno nesposoban u kriptografiji i savjetujem svima da krenu od ove teze (pa, možda osim tebe i onog cool tipa tamo). Međutim, na ovaj ili onaj način, u procesu rada nastaju problemi vezani za zaštitu podataka i oni se moraju rješavati. Stoga vam predstavljam prijevod članka finskog programera Timo H, koji mi je bio prilično zanimljiv i koristan.

Ovo je brzi vodič o tome kako izbjeći uobičajene zamke sa simetričnim šifriranjem u PHP-u.

Razmotrit ćemo slučaj kada se podaci obrađuju na strani servera (konkretno, šifriranje se događa na serveru, a podaci se mogu primiti, na primjer, od klijenta u obliku čistog teksta, lozinke itd.), što je tipičan slučaj za PHP aplikacije.

Informacije u ovom vodiču ne treba da se koriste za kreiranje šifrovanih mrežnih veza koje imaju složenije zahteve. U takvim slučajevima morate koristiti špijunirani ili TLS.

Naravno, ovdje date preporuke nisu „jedini mogući način” za organiziranje enkripcije u PHP-u. Svrha ovog vodiča je pokušati ostaviti manje prostora za greške i teške, dvosmislene odluke.

Funkcije šifriranja u PHP-u

Koristite Mcrypt ili OpenSSL ekstenzije.

Algoritam šifriranja i njegov način rada, jednokratni kod (vektor inicijalizacije)

Koristite AES-256 u CTR modu sa nasumičnim jednokratnim kodom ( cca. prijevod: nonce). AES je standard, tako da možete koristiti funkcije bilo koje ekstenzije - Mcrypt ili OpenSSL.

Uvijek generirajte novi jednokratni kod. U ovom slučaju morate koristiti kriptografski siguran izvor nasumičnih brojeva. U nastavku pročitajte malo više o generiranju slučajnih brojeva. Jednokratni kod nije tajna i može se spojiti sa šifriranim tekstom za prijenos i naknadno dešifriranje.

Jednokratni kod mora biti dugačak 128 bita (16 bajtova), samo niz bajtova bez ikakvog kodiranja.

U proširenju Mcrypt, AES je poznat kao Rijndael-128 ( cca. prev.: uprkos činjenici da govorimo o AES-256, ovo nije greška. AES-256 != Rijndael-256). U OpenSSL-u, respektivno, AES-256-CTR.

Primjer korištenja Mcrypt:
OpenSSL primjer:
Provjerite funkcionira li enkripcija ispravno koristeći test vektore ( cca. prevod: za AES-256-CTR vidi paragraf F.5.5 na strani 57).

Za CTR način rada, postoje određena ograničenja za ukupan volumen šifriranih podataka. Možda se nećete susresti sa ovim u praksi, ali imajte na umu da ne biste trebali šifrirati više od 2^64 bajta podataka jednim ključem, bez obzira da li je riječ o jednoj dugačkoj poruci ili više kratkih.

CTR način ostaje stabilan samo ako ne koristite isti jednokratni kod s istim ključem. Iz tog razloga, važno je generirati jednokratne kodove koristeći kriptografski jak izvor slučajnosti. Dodatno, to znači da ne biste trebali šifrirati više od 2^64 poruke jednim ključem. Pošto je dužina jednokratnog koda 128 bita, ograničenje broja poruka (i njihovih odgovarajućih jednokratnih kodova) od 2^128/2 je važno zbog rođendanskog paradoksa ( cca. prijevod:).

I zapamtite da enkripcija neće sakriti činjenicu koliko podataka šaljete. Kao primjer ekstremnog slučaja, ako šifrirate poruke koje sadrže samo "da" ili "ne", očito šifriranje neće sakriti te informacije.

Provjera autentičnosti podataka

Uvijek provjerite autentičnost i integritet podataka.
Da biste to učinili, koristite MAC nakon šifriranja. One. Prvo se podaci šifriraju, a zatim se HMAC-SHA-256 uzima iz rezultirajućeg šifratnog teksta, uključujući sam šifrirani tekst i jednokratni kod.

Prilikom dešifriranja, prvo provjerite HMAC koristeći algoritam za upoređivanje koji je otporan na vremenske napade. Nemojte direktno porediti $user_submitted_mac i $calculated_mac koristeći == ili === operatore poređenja. Još je bolje koristiti "HMAC dvostruku provjeru".

Ako je HMAC provjera uspješna, dešifriranje se može izvesti bezbedno. Ako HMAC nije prikladan, odmah isključite.

Ključevi za šifriranje i autentifikaciju

U idealnom slučaju, koristite ključeve izvedene iz kriptografski jakog izvora slučajnosti. AES-256 zahtijeva 32 bajta nasumičnih podataka („sirovi“ string – niz bitova bez korištenja bilo kakvog kodiranja).

Ako aplikacija radi pod PHP verzijom ispod 5.5, koja nema ugrađenu implementaciju PBKDF2, onda ćete morati koristiti vlastitu implementaciju u PHP-u, čiji primjer možete pronaći ovdje: https://defuse. ca/php-pbkdf2.htm. Imajte na umu da oslanjanje na vlastitu implementaciju možda neće ispravno riješiti ključ kao što to radi ugrađena funkcija hash_pbkdf2().

Nemojte koristiti isti ključ za šifriranje i autentifikaciju. Kao što je gore navedeno, 32 bajta su potrebna za ključ za šifriranje i 32 bajta za ključ za autentifikaciju (HMAC). Sa PBKDF2 možete uzeti 64 bajta od lozinke i koristiti, recimo, prva 32 bajta kao ključ za šifriranje, a preostala 32 bajta za ključ za autentifikaciju.

Ako su vaše lozinke pohranjene u datoteci, na primjer, kao HEX niz, nemojte ih ponovo kodirati prije nego što ih unesete u funkcije šifriranja. Umjesto toga, koristite PBKDF2 za pretvaranje HEX kodiranih ključeva direktno u visokokvalitetni ključ za šifriranje ili autentifikaciju. Ili koristite SHA-256 bez dodatnog izlaza kodiranja (samo niz od 32 bajta) za heširanje lozinki. Korišćenje redovnog heširanja lozinki obezbeđuje dovoljno entropije. Više detalja je dato u sljedećim paragrafima.

Key stretch

Prvo, trebali biste izbjegavati korištenje ključeva niske entropije. Ali ipak, ako trebate koristiti, na primjer, korisničke lozinke, onda svakako morate koristiti PBKDF2 s velikim brojem iteracija kako biste maksimizirali sigurnost ključa.

Jedan od parametara PBKDF2 je broj iteracija heširanja. I što je veći, to je veća sigurnost ključa na koju možete računati. Ako vaš kod radi na 64-bitnoj platformi, koristite SHA-512 kao algoritam za heširanje za PBKDF2. Za 32-bitnu platformu koristite SHA-256.

Međutim, nije moguće koristiti relativno veliki broj iteracija u online aplikacijama zbog rizika od DoS napada. Stoga ključni kvalitet neće biti tako visok kao u offline aplikacijama, koje mogu priuštiti veliki broj iteracija bez takvog rizika. U pravilu, za online aplikacije, odabire se toliki broj iteracija heširanja tako da PBKDF2 ne traje više od 100 ms.

U slučaju da možete koristiti lozinke visoke entropije, nije potrebno da ih rastežete kao za lozinke sa niskom entropijom. Na primjer, ako kreirate "encryption_master_key" i "auth_master_key" koristeći /dev/urandom, onda uopće nema potrebe za PBKDF2. Samo budite sigurni da koristite ključeve kao sekvence bitova, bez ikakvog kodiranja.

Osim toga, s PBKDF2 nije teško dobiti i ključeve za šifriranje i autentifikaciju iz jedne glavne lozinke (samo koristite mali broj iteracija ili čak jednu). Ovo je korisno ako imate samo jednu "glavnu lozinku" koja se koristi i za šifriranje i za autentifikaciju.

Čuvanje i upravljanje ključevima

Najbolja stvar je da koristite poseban namenski uređaj za pohranu ključeva (HSM).

Ako to nije moguće, onda da bi se zakomplikovao napad, može se koristiti enkripcija datoteke ključa ili konfiguracijske datoteke (koja pohranjuje stvarne ključeve za šifriranje/autentifikaciju) pomoću ključa pohranjenog na zasebnoj lokaciji (izvan matičnog direktorija ili korijena stranice) . Na primjer, možete koristiti varijablu okruženja Apache u httpd.conf za pohranjivanje ključa potrebnog za dešifriranje stvarne datoteke ključeva:
SetEnv keyfile_key crypto_strong_high_entropy_key # Možete pristupiti ovoj varijabli u PHP-u koristeći $_SERVER["keyfile_key"] # Ostatak konfiguracije
Sada, ako su datoteke u korijenu web-mjesta i ispod, uključujući datoteke s ključevima, ugrožene (na primjer, ako je sigurnosna kopija procurila), šifrirani podaci će ostati sigurni jer ključ pohranjen u varijablu okruženja nije kompromitovan. Važno je zapamtiti da httpd.conf fajlove treba posebno praviti rezervnu kopiju, a ne kompromitovati promenljivu keyfile_key kroz, na primer, izlaz phpinfo().

Ako koristite datoteku umjesto konfiguracijskog parametra, moguće je organizirati rotaciju ključa. U najgorem slučaju, ako je protivnik dobio vaše ključeve za šifriranje i autentifikaciju, a da ga ne primijetite, rotiranje ključeva u određenim intervalima može ograničiti njihov pristup (pod pretpostavkom da ne može dobiti nove ključeve). Ova tehnika će pomoći u smanjenju štete jer neprijatelj neće moći beskrajno koristiti kompromitirane ključeve.

Kompresija podataka

Općenito, ne biste trebali komprimirati izvorni tekst prije nego što ga šifrirate. Ovo može dati neprijatelju dodatni alat za analizu.

Na primjer, ako podatke sesije pohranjujete u šifrirane kolačiće, od kojih su neki dostavljeni od strane korisnika, a neki predstavljaju tajne informacije, protivnik može saznati dodatne informacije o tajni slanjem, kao običan korisnik, neke posebno kreirane podatke i mjerenje kako se mijenja dužina rezultirajućih šifriranih tekstova.

Tekst se efikasnije kompresuje ako postoje područja koja se ponavljaju. Manipulirajući korisničkim podacima, možete ih odabrati tako da se djelomično podudaraju s tajnim podacima. Što je veće podudaranje, manji će šifrirani tekst biti u izlazu. Ova vrsta napada se zove ZLOČIN.

Ako nemate tešku potrebu za komprimiranjem podataka, nemojte ih komprimirati.

Serversko okruženje

Kao opće pravilo, ne biste trebali hostirati sigurnosno osjetljive aplikacije na zajedničkom serveru. Na primjer, na dijeljenom hostingu, gdje protivnik može pristupiti virtuelnoj mašini na istom fizičkom serveru kao i vi.

Postoje razni razlozi koji dijeljene servere čine sumnjivim mjestom za hostovanje sigurnosnih kritičnih aplikacija. Na primjer, nedavno su demonstrirani napadi između virtuelnih servera: eprint.iacr.org/2014/248.pdf. Ovo je dobar podsjetnik da se ofanzivne tehnike ne degradiraju, već se vremenom usavršavaju i poboljšavaju. Takve zamke uvijek se moraju uzeti u obzir.

Stručne konsultacije

Na kraju, ali ne i najmanje važno, konsultujte stručnjaka da pregleda vaš sigurnosni kod.

(PHP 4, PHP 5, PHP 7)

crypt — Jednosmjerno heširanje niza

Upozorenje

Ova funkcija (još) nije binarno sigurna!

Opis

kripta (string $str [, string $salt]): string

kripta()će vratiti heširani niz koristeći standardni Unix DES algoritam ili alternativne algoritame koji mogu biti dostupni na sistemu.

Parametar soli nije obavezan. Kako god, kripta() stvara slab heš bez soli. PHP 5.6 ili noviji pokreće E_NOTICE grešku bez toga. Obavezno navedite dovoljno jaku sol za bolju sigurnost.

password_hash() koristi jak heš, stvara jaku sol i automatski primjenjuje odgovarajuće runde. password_hash() je jednostavan kripta() omotač i kompatibilan s postojećim hashovima lozinki. Korištenje password_hash() ohrabruje se.

Neki operativni sistemi podržavaju više od jedne vrste hash-a. U stvari, ponekad se standardni algoritam baziran na DES-u zamjenjuje algoritmom baziranim na MD5. Hash tip se pokreće argumentom soli. Pre verzije 5.3, PHP bi određivao dostupne algoritme u vreme instalacije na osnovu sistemske crypt(). Ako nema soli, PHP će automatski generisati ili standardnu ​​dvoznakovnu (DES) sol, ili dvanaest karaktera ( MD5), u zavisnosti od dostupnosti MD5 crypt(). PHP postavlja konstantu named CRYPT_SALT_LENGTHšto označava najdužu validnu sol koju dozvoljavaju dostupni hashovi.

Standardni DES baziran kripta() vraća sol kao prva dva znaka izlaza. Također koristi samo prvih osam znakova str , tako da će duži nizovi koji počinju sa istih osam znakova generirati isti rezultat (kada se koristi ista sol).

Na sistemima u kojima funkcija crypt() podržava više tipova hash-a, sljedeće konstante su postavljene na 0 ili 1 ovisno o tome da li je dati tip dostupan:

  • CRYPT_STD_DES- Standardni hash baziran na DES-u sa dvoznakom soli iz abecede "./0-9A-Za-z". Korištenje nevažećih znakova u soli će uzrokovati neuspjeh crypt().
  • CRYPT_EXT_DES- Prošireni hash baziran na DES-u. "Sol" je niz od 9 znakova koji se sastoji od donje crte praćene 4 bajta broja iteracija i 4 bajta soli. Oni su kodirani kao znakovi koji se mogu ispisati, 6 bitova po karakteru, prvi znak sa najmanjim značajem. Vrijednosti od 0 do 63 su kodirane kao "./0-9A-Za-z". Korištenje nevažećih znakova u soli će uzrokovati neuspjeh crypt().
  • CRYPT_MD5- MD5 heširanje sa dvanaest znakova soli počevši od $1$
  • CRYPT_BLOWFISH- Blowfish heširanje sa solju na sljedeći način: "$2a$", "$2x$" ili "$2y$", dvocifreni parametar cijene, "$" i 22 znaka iz abecede "./0-9A- Za-z". Upotreba znakova izvan ovog raspona u soli će uzrokovati da crypt() vrati string nulte dužine. Dvocifreni parametar troškova je logaritam osnove 2 broja iteracija za osnovni algoritam heširanja zasnovanog na Blowfish-u i mora biti u rasponu 04-31, vrijednosti izvan ovog raspona će uzrokovati neuspjeh crypt(). Verzije PHP-a prije 5.3.7 podržavaju samo "$2a$" kao solni prefiks: PHP 5.3.7 je uveo nove prefikse da popravi sigurnosnu slabost u implementaciji Blowfish. Molimo pogledajte za sve detalje sigurnosne ispravke, ali da rezimiramo, programeri koji ciljaju samo PHP 5.3.7 i novije verzije bi trebali koristiti "$2y$" umjesto "$2a$".
  • CRYPT_SHA256- SHA-256 hash sa šesnaest znakova soli sa prefiksom od $5$. Ako solni niz počinje sa "rounds=
  • CRYPT_SHA512- SHA-512 hash sa šesnaest znakova soli sa prefiksom od $6$. Ako solni niz počinje sa "rounds= $", numerička vrijednost N se koristi za označavanje koliko puta heš petlja treba biti izvršena, slično kao parametar troška na Blowfish-u. Zadani broj rundi je 5000, postoji minimum 1000 i maksimum 999,999,999. Svaki odabir N izvan ovog raspona bit će skraćen na najbližu granicu.

Od PHP 5.3.0, PHP sadrži sopstvenu implementaciju i koristiće je ako sistemu nedostaje podrška za jedan ili više algoritama.

Parametri

Niz koji se hešira.

Oprez

Koristeći CRYPT_BLOWFISH algoritam, rezultirat će skraćivanjem str parametra na maksimalnu dužinu od 72 znaka.

Opcionalni slani niz za zasnivanje heširanja. Ako nije navedeno, ponašanje je definirano implementacijom algoritma i može dovesti do neočekivanih rezultata.

Povratne vrijednosti

Vraća raspršeni niz ili niz koji je kraći od 13 znakova i zajamčeno se razlikuje od soli u slučaju neuspjeha.

Upozorenje

Prilikom provjere valjanosti lozinki, funkcija za upoređivanje nizova koja nije osjetljiva na napade na vrijeme treba se koristiti za upoređivanje izlaza kripta() na prethodno poznati hash. PHP 5.6 i dalje nudi hash_equals() za ovu svrhu.

Dnevnik promjena

Verzija Opis
5.6.5 Kada je niz greške "*0" dat kao sol, "*1" će sada biti vraćeno radi dosljednosti s drugim implementacijama kripte. Pre ove verzije, PHP 5.6 bi pogrešno vraćao DES heš.
5.6.0 Podignite E_NOTICE sigurnosno upozorenje ako je sol izostavljena.
5.5.21 Kada je niz greške "*0" dat kao sol, "*1" će sada biti vraćeno radi dosljednosti s drugim implementacijama kripte. Prije ove verzije, PHP 5.5 (i ranije grane) bi pogrešno vraćale DES hash.
5.3.7 Dodano $2x$ i $2y$ Blowfish načini za rješavanje potencijalnih high-bit napada.
5.3.2 Dodata SHA-256 i SHA-512 kripta bazirana na » implementaciji Ulricha Dreppera.
5.3.2 Ispravljeno ponašanje Blowfish u nevažećim rundama za vraćanje niza "neuspjeh" ("*0" ili "*1"), umjesto vraćanja na DES.
5.3.0 PHP sada sadrži vlastitu implementaciju za algoritme MD5 crypt, Standard DES, Extended DES i Blowfish i koristit će to ako sistemu nedostaje podrška za jedan ili više algoritama.

Primjeri

Primjer #1 kripta() primjeri

$hashed_password = crypt("moja lozinka"); // neka se sol automatski generira

/* Trebali biste proslijediti cijele rezultate crypt() kao sol za poređenje a
lozinku, kako biste izbjegli probleme kada se koriste različiti algoritmi heširanja. (Kao
gore piše, standardno DES-bazirano heširanje lozinke koristi sol od 2 znaka,
ali heširanje zasnovano na MD5 koristi 12.) */
if (hash_equals ($hashed_password, kripta ($user_input, $hashed_password ))) (
echo "Lozinka provjerena!" ;
}
?>

Primjer #2 Upotreba kripta() sa htpasswd

// Postavi lozinku
$password = "moja lozinka" ;

// Dobiti hash, puštajući da se sol automatski generiše
$hash = kripta($lozinka);
?>

Primjer #3 Korištenje kripta() sa različitim tipovima heša

/* Ove soli su samo primjeri i ne treba ih koristiti doslovno u vašem kodu.
Trebali biste generirati posebnu, ispravno formatiranu sol za svaku lozinku.
*/
if (CRYPT_STD_DES == 1 ) (
echo "Standardni DES: " . kripta ("rasmuslerdorf" , "rl") . "\n" ;
}

if (CRYPT_EXT_DES == 1 ) (
echo "Prošireni DES: " . kripta ("rasmuslerdorf" , "_J9..rasm" ) . "\n" ;
}

if (CRYPT_MD5 == 1 ) (
echo "MD5: " . kripta ("rasmuslerdorf" , "$1$rasmusle$" ) . "\n" ;
}

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

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

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

Bilo koja informacija može biti šifrovana ili dešifrovana, uključujući korišćenje PHP-a. Ovaj jezik ima mnogo mogućnosti šifriranja podataka, od jednostavnih do složenih.

Pogledajmo osnovne metode šifriranja

base64- omogućava vam šifriranje i dešifriranje podataka pomoću MIME base64 algoritma. Ne koristi ključeve i često se koristi za skrivanje veza u PHP-u.

primjeri:
//šifriranje teksta
$text = "Link";
echo base64_encode($text); //Proizvodi: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==
//dešifriranje
echo base64_decode("PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==");
?>

Kao što vidite, prvo smo koristili operaciju base64_encode i dobili šifru: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==, a zatim ga zamijenio u base64_decode i vratio vezu.

md5- omogućava jednostrano heširanje podataka. To jest, za razliku od base64, više ih nećete moći dešifrirati natrag. Često se md5 koristi za pohranjivanje lozinki u bazi podataka, ali nedavno je šifrovanu kombinaciju md5 postalo lako pronaći u tabelama za dešifriranje, koje su ljubazno pružene mnoge stranice i algoritmi. Stoga je za pohranjivanje md5 lozinki bolje algoritme zamijeniti Blowfishom.

primjer:

//šifriranje teksta
echo md5("kombinacija");
?>

Šifriranje ključem

I posljednji primjer enkripcije/dešifriranja o kojem sam želio govoriti koristi ključ (kao lozinku). To jest, prosljeđujete jedinstveni ključ funkciji šifriranja, a kod se šifrira zajedno s njim. Da biste dešifrirali, morate dati funkciji šifrirani kod i ključ koji samo vi znate. Primjer korištenja funkcija na samom dnu koda.

funkcija __encode($text, $key) (



$enc_text=base64_encode(mcrypt_generic($td,$iv.$text));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $enc_text; ) )
funkcija strToHex($string) (
$hex="";
za ($i=0; $i< strlen($string); $i++) { $hex .= dechex(ord($string[$i])); }
return $hex; )
funkcija __decode($text, $key) (
$td = mcrypt_module_open("trostruki", "", "cfb", "");
$iv_size = mcrypt_enc_get_iv_size($td);
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
if (mcrypt_generic_init ($td, $key, $iv) != -1) (
$decode_text = substr(mdecrypt_generic($td, base64_decode($text)),$iv_size);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $decode_text; ) )
funkcija hexToStr($hex) (
$string="";
za ($i=0; $i< strlen($hex)-1; $i+=2) { $string .= chr(hexdec($hex[$i].$hex[$i+1])); }
return $string; )

$str = "Banovi koje treba šifrovati!
Po ključu";
$code = strToHex(__encode($str, "My#key-do-36-simvolov"));
echo "Šifrirani kod: ".$code."
";

$str = __decode(hexToStr($code), "My#key-do-36-simvolov");
echo "Dešifrovani kod: ".$str."
";
?>

Možete šifrirati html sadržaj. Dužina ključa ne smije biti veća od 36 znakova.

Ova metoda se može koristiti za šifriranje nekih podataka i njihovo postavljanje u txt datoteku ili bazu podataka i primanje pomoću dešifriranja pomoću ključa.

Naravno, bilo koji kod se može dešifrirati/hakovati i to nije izuzetak, stoga koristite jake metode šifriranja.

Jedna od osnovnih istina kriptografije je da ne biste trebali ništa izmišljati u ovoj oblasti osim ako niste profesionalac. To je djelimično tačno, jer je sve najbolje odavno izmišljano, trpelo i decenijama korišćeno u oblasti informacionih tehnologija. Druga strana istine je da se razvoj određene oblasti znanja odvija samo uz stalni priliv svježih ideja i originalnih rješenja u nju.

Iz očiglednih razloga, nećemo ciljati na divove industrijske kriptografije poput AES-a, već ćemo se, da tako kažemo, upustiti u vlastita kriptografska istraživanja s blekdžekom i radošću.

Djelomično zato što je zanimljivo, dijelom zato što modelirajući nešto svoje i upoređujući to sa priznatim standardima, jasno vidite kontrast, efikasna rješenja i potpune propuste, i shvaćate čemu možete težiti kako biste poboljšali efikasnost.

Ali već dovoljno vode.

Recimo da je naša web aplikacija napisana u PHP-u, potrebna joj je reverzibilna enkripcija, i vjerujemo da možemo napisati svoj vlastiti sistem šifriranja.

Dakle, napišimo naš vlastiti reverzibilni sistem šifriranja s privatnim i javnim ključevima, onaj koji će imati sljedeće karakteristike manje ili više sigurnog kriptografskog algoritma:

  1. Prisutnost simbola buke u konačnoj šifri.
  2. Informacije u svakom kanalu pošiljatelja i odredišta bit će šifrirane korištenjem privatnog ključa, a funkcija podudaranja će biti jedinstvena za svaki ključ.
  3. Svaka poruka će dobiti sažetak koda - jedinstveni kod koji je funkcija privatnog ključa i originalne poruke. Ovo je potrebno kako bi se postigla jedinstvenost funkcije podudaranja "izvornog simbola".<=>kodirani simbol“ ne samo za kanal „Pošiljalac-primalac“, već i za svaku pojedinačnu poruku.

    Dakle, čak i ako zamislimo da je korespondencija kodiranih i originalnih simbola za određenu poruku postala poznata korištenjem kriptografske analize, na primjer, frekvencijske analize, to ne daje nikakve preferencije pri proučavanju druge poruke.

  4. Da bismo zakomplikovali analizu frekvencije, svaki početni simbol poruke ćemo kodirati sa dva simbola šifre.
Pa šta se desilo.

U stvari, možete vidjeti konačni rezultat

Klasa SymCoder uključuje metode šifriranja i dešifriranja.

Šifrovanje se vrši metodom code(), koja uzima originalnu poruku kao ulaz.

Ovde, poruka iz generisane tabele korespondencije u tab_coded kreira šifrovanu poruku, razblaženu duž ivica i iznutra sa simbolima šuma.

Usput, simboli buke su jedinstveni za svaki kanal pošiljaoca-odredišta, jer se generišu pomoću ključa kanala, ali nisu jedinstveni za poruke. Simboli koji se koriste za šifriranje u code_symbols su neki znaci interpunkcije i simboli poput %, @, itd.

Za svaki kodirani simbol postoje dva simbola iz code_symbols, iz očiglednih razloga što ih ima nekoliko puta manje od kodiranih simbola.

Tabela korespondencije create_tab_coded izgrađena je pomoću prijevoda heša ključa poruke u niz s brojem elemenata jednakim broju elemenata u nizu simbola koda. Početna pozicija za prelazak dvoznakovnih kodova je također uvijek različita i povezana je s ključem kanala. Ovo omogućava da budemo sigurni da će algoritam za prelazak kodiranih simbola i uparivanje kodnih simbola s njima uvijek (ili garantirano često) biti drugačiji.

Na primjer, poruka "zdravo svijet", kada je kodirana, izgleda ovako:

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

I evo iste poruke, ponovo kodirane:

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

Vidi se da je sažetak iste poruke isti, ali šifra postaje drugačija - simboli buke se dodaju u proizvoljnom podudaranju i proizvoljnim redoslijedom za svaku novu enkripciju.

Poruke imaju redundantnost, koja se smanjuje kako se jačina poruke povećava, do 10% šuma (za najkraće poruke šum dostiže 90% ili veći procenat), minimalna dužina šifrovane poruke je 116 karaktera. Jedan od nedostataka ove metode šifriranja je da se kodirane poruke barem udvostruče.

Dekodiranje se sastoji od obrnutog prijevoda forme “simbola koda” - originalnog simbola sa izrezanim šumom iz poruke. Šta bi mogao biti ključ? U osnovi, bilo koji niz koji je jedinstven za svaki par odredište-primalac.

Na primjer, ako kreirate messenger sa enkripcijom poruka, tada bi najjednostavnija verzija privatnog ključa mogla biti md5($user_id_1. $salt. $user_id_2), tada će ključ biti jedinstven za svaki kanal za poruke.

Recimo da trebate razmjenjivati ​​podatke između dva servera. Radi zaštite podataka od prisluškivanja saobraćaja, podaci su šifrirani. Pa, na primjer, prijenos akcija unutar botneta. To je ono što u suštini nije enkripcija, već se zove kodiranje, a dobro poznate funkcije se koriste za dekodiranje takvog koda.

Kao još jedan primjer pseudo-šifriranja navešću primjer “šifriranja” lozinki u bazi podataka jednog CMS-a - tamo lozinke nisu šifrirane u md5() ili , već jednostavno kodirane preko base64. One. Kada baza podataka procuri, hakeru neće biti teško da dešifruje sve lozinke koristeći ugrađenu PHP funkciju base64_decode().

Moramo prenijeti podatke bez brige da će neko uspjeti presresti tekst i dešifrirati ga. PHP ima popularan paket za šifrovanje podataka pod nazivom Mcrypt, koji obezbeđuje dvosmernu enkripciju (to jest, stvarno šifrovanje i dešifrovanje podataka).

Mcrypt verzija 2.4.7 podržava sljedeće algoritme simetričnog šifriranja: 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, itd. Više detalja o svakom algoritmu je napisano na Wikipediji.

Pošto se koristi simetrična enkripcija, ključ mora biti poznat objema stranama i čuvan u tajnosti.

Primjer enkripcije i dešifriranja niza

mcrypt_module_open("des", "", "ecb", "")
Ova funkcija otvara algoritamski modul i korišteni način rada. Za ovaj primjer, DES algoritam je u ECB modu.

$key = substr($key, 0, mcrypt_enc_get_key_size($td));
Maksimalna veličina ključa se mora dobiti pozivanjem funkcije mcrypt_enc_get_key_size() i svaka vrijednost manja od ove bit će ispravna.

$s = mcrypt_generic($td, $source);
Prilikom šifriranja, podaci se popunjavaju nula bajtova kako bi se osiguralo da su podaci dugački n*blokova. Veličina bloka je određena algoritmom (za DES veličina bloka je 64 bita). Stoga, prilikom dešifriranja, "\0" se može pojaviti na kraju reda, koji se uklanja funkcijom trim()