Kryptering i PHP. Krypter, dekrypter data ved hjelp av en nøkkel i PHP Kryptering og autentiseringsnøkler

  • Oversettelse
  • Opplæringen

Fra oversetteren: I prosessen med programmering glemmer jeg aldri at jeg er farlig inkompetent i kryptografi, og jeg råder alle til å gå videre fra denne oppgaven (vel, kanskje bortsett fra deg og den kule fyren der borte). Men på en eller annen måte, i prosessen med arbeidet, oppstår problemer knyttet til databeskyttelse, og de må løses. Derfor bringer jeg til deg en oversettelse av en artikkel av den finske utvikleren Timo H, som jeg fant ganske interessant og nyttig.

Dette er en rask guide til hvordan du unngår vanlige fallgruver med symmetrisk kryptering i PHP.

Vi vil vurdere tilfellet når dataene behandles på serversiden (spesielt skjer kryptering på serveren, og dataene kan mottas for eksempel fra klienten i form av klartekst, passord, etc.), som er et typisk tilfelle for PHP-applikasjoner.

Informasjonen i denne veiledningen skal ikke brukes til å lage krypterte nettverkstilkoblinger som har mer komplekse krav. For slike tilfeller må du bruke spied eller TLS.

Naturligvis er anbefalingene gitt her ikke den "eneste mulige måten" å organisere kryptering i PHP. Hensikten med denne veiledningen er å prøve å gi mindre rom for feil og vanskelige, tvetydige beslutninger.

Krypteringsfunksjoner i PHP

Bruk Mcrypt- eller OpenSSL-utvidelser.

Krypteringsalgoritme og dens driftsmodus, engangskode (initialiseringsvektor)

Bruk AES-256 i CTR-modus med en tilfeldig engangskode ( ca. oversettelse: nonce). AES er en standard, så du kan bruke funksjonene til alle utvidelsene - Mcrypt eller OpenSSL.

Generer alltid en ny engangskode. I dette tilfellet må du bruke en kryptografisk sikker kilde med tilfeldige tall. Les litt mer om generering av tilfeldige tall nedenfor. Engangskoden er ikke en hemmelighet, og kan settes sammen med chiffertekst for overføring og påfølgende dekryptering.

Engangskoden må være 128 biter (16 byte) lang, bare en streng med byte uten noen koding.

I Mcrypt-utvidelsen er AES kjent som Rijndael-128 ( ca. overs.: til tross for at vi snakker om AES-256, er dette ikke en feil. AES-256 != Rijndael-256). I OpenSSL, henholdsvis AES-256-CTR.

Eksempel på Mcrypt-bruk:
OpenSSL eksempel:
Bekreft at kryptering fungerer riktig ved å bruke testvektorer ( ca. oversettelse: for AES-256-CTR, se avsnitt F.5.5 på side 57).

For CTR-modus er det noen begrensninger på det totale volumet av krypterte data. Du vil kanskje ikke støte på dette i praksis, men husk at du ikke bør kryptere mer enn 2^64 byte med data med én nøkkel, uansett om det er én lang melding eller mange korte.

CTR-modusen forblir stabil bare hvis du ikke bruker den samme engangskoden med samme nøkkel. Av denne grunn er det viktig å generere engangskoder ved å bruke en kryptografisk sterk kilde til tilfeldighet. I tillegg betyr dette at du ikke bør kryptere mer enn 2^64 meldinger med en enkelt nøkkel. Siden lengden på engangskoden er 128 biter, er grensen for antall meldinger (og deres tilsvarende engangskoder) på 2^128/2 viktig på grunn av bursdagsparadokset ( ca. oversettelse:).

Og husk at kryptering ikke skjuler hvor mye data du sender. Som et eksempel på et ekstremt tilfelle, hvis du krypterer meldinger som bare inneholder "ja" eller "nei", vil tydeligvis ikke kryptering skjule denne informasjonen.

Dataautentisering

Sjekk alltid ektheten og integriteten til dataene.
For å gjøre dette, bruk MAC etter kryptering. De. Først blir dataene kryptert, og deretter hentes HMAC-SHA-256 fra den resulterende chifferteksten, inkludert selve chifferteksten og engangskoden.

Når du dekrypterer, sjekk først HMAC ved å bruke en sammenligningsalgoritme som er motstandsdyktig mot timingangrep. Ikke sammenlign $user_submitted_mac og $calculated_mac direkte ved å bruke == eller === sammenligningsoperatorene. Det er enda bedre å bruke "HMAC double check".

Hvis HMAC-kontrollen er vellykket, kan dekryptering utføres trygt. Hvis HMAC ikke er egnet, slå av umiddelbart.

Krypterings- og autentiseringsnøkler

Ideelt sett bør du bruke nøkler avledet fra en kryptografisk sterk kilde til tilfeldighet. AES-256 krever 32 byte med tilfeldige data (en "rå" streng - en sekvens av biter uten bruk av noen koding).

Hvis applikasjonen kjører under PHP-versjon under 5.5, som ikke har en innebygd implementering av PBKDF2, må du bruke din egen implementering i PHP, et eksempel på dette finner du her: https://defuse. ca/php-pbkdf2.htm. Vær oppmerksom på at det å stole på din egen implementering kanskje ikke løser nøkkelen riktig slik den innebygde hash_pbkdf2()-funksjonen gjør.

Ikke bruk samme nøkkel for kryptering og autentisering. Som nevnt ovenfor kreves det 32 ​​byte for krypteringsnøkkelen og 32 byte for autentiseringsnøkkelen (HMAC). Med PBKDF2 kan du ta 64 byte fra passordet og bruke for eksempel de første 32 bytene som krypteringsnøkkel, og de resterende 32 bytene for autentiseringsnøkkelen.

Hvis passordene dine er lagret i en fil, for eksempel som en HEX-streng, må du ikke kode dem på nytt før du mater dem til krypteringsfunksjonene. Bruk i stedet PBKDF2 til å konvertere HEX-kodede nøkler direkte til en krypterings- eller autentiseringsnøkkel av høy kvalitet. Eller bruk SHA-256 uten ekstra kodingsutgang (bare en 32 byte streng) for å hash passord. Bruk av vanlig passordhashing gir nok entropi. Flere detaljer er gitt i de følgende avsnittene.

Nøkkelstrekk

Først bør du unngå å bruke laventropinøkler. Men likevel, hvis du trenger å bruke for eksempel brukerpassord, må du definitivt bruke PBKDF2 med et stort antall iterasjoner for å maksimere nøkkelsikkerheten.

En av parameterne til PBKDF2 er antall hashing-iterasjoner. Og jo høyere den er, jo større er sikkerheten til nøkkelen du kan stole på. Hvis koden din kjører på en 64-biters plattform, bruk SHA-512 som hashing-algoritme for PBKDF2. For en 32-biters plattform, bruk SHA-256.

Det er imidlertid ikke mulig å bruke et relativt høyt antall iterasjoner i nettapplikasjoner på grunn av risikoen for et DoS-angrep. Derfor vil ikke nøkkelkvaliteten være like høy som i offline-applikasjoner, som har råd til et stort antall iterasjoner uten slik risiko. Som regel, for nettbaserte applikasjoner, velges et slikt antall hashing-iterasjoner slik at PBKDF2 ikke tar mer enn 100 ms.

I tilfelle du kan bruke passord med høy entropi, er det ikke nødvendig å strekke det slik du ville gjort for passord med lav entropi. Hvis du for eksempel oppretter en "encryption_master_key" og en "auth_master_key" ved å bruke /dev/urandom, er det ikke behov for PBKDF2 i det hele tatt. Bare pass på å bruke tastene som sekvenser av biter, uten noen koding.

I tillegg, med PBKDF2 er det ikke vanskelig å få både krypterings- og autentiseringsnøkler fra et enkelt hovedpassord (bare bruk et lite antall iterasjoner eller til og med en). Dette er nyttig hvis du bare har ett "hovedpassord" brukt for både kryptering og autentisering.

Oppbevaring og administrasjon av nøkkel

Det beste er å bruke en separat dedikert nøkkellagringsenhet (HSM).

Hvis dette ikke er mulig, kan man for å komplisere angrepet bruke kryptering av nøkkelfilen eller konfigurasjonsfilen (som lagrer selve krypterings-/autentiseringsnøklene) ved å bruke en nøkkel lagret på et eget sted (utenfor hjemmekatalogen eller nettstedroten) . For eksempel kan du bruke en Apache-miljøvariabel i httpd.conf for å lagre nøkkelen som trengs for å dekryptere selve nøkkelfilen:
SetEnv keyfile_key crypto_strong_high_entropy_key # Du kan få tilgang til denne variabelen i PHP ved å bruke $_SERVER["keyfile_key"] # Resten av konfigurasjonen
Nå, hvis filer i roten av nettstedet og nedenfor, inkludert filer med nøkler, blir kompromittert (for eksempel hvis en sikkerhetskopi lekkes), vil de krypterte dataene forbli trygge fordi nøkkelen som er lagret i miljøvariabelen ikke har blitt kompromittert. Det er viktig å huske at httpd.conf-filer bør sikkerhetskopieres separat, og ikke kompromittere keyfile_key-variabelen gjennom for eksempel utdata fra phpinfo().

Hvis du bruker en fil i stedet for en konfigurasjonsparameter, er det mulig å organisere nøkkelrotasjon. I verste fall, hvis en motstander har skaffet seg krypterings- og autentiseringsnøklene dine uten å bli lagt merke til, kan rotering av nøklene med enkelte intervaller begrense tilgangen deres (forutsatt at de ikke kan skaffe nye nøkler). Denne teknikken vil bidra til å redusere skaden fordi fienden ikke vil være i stand til å bruke kompromitterte nøkler på ubestemt tid.

Datakomprimering

Generelt bør du ikke komprimere kildeteksten før du krypterer den. Dette kan gi fienden et ekstra verktøy for analyse.

Hvis du for eksempel lagrer øktdata i krypterte informasjonskapsler, hvorav noen er levert av brukeren og noen representerer hemmelig informasjon, kan en motstander lære ytterligere informasjon om hemmeligheten ved å sende, som en vanlig bruker, noen spesiallagde data og måle hvordan lengden på de resulterende chiffertekstene endres.

Tekst komprimeres mer effektivt hvis det er gjentakende områder. Ved å manipulere brukerdata kan du velge det slik at det delvis faller sammen med hemmelige data. Jo større samsvar, jo mindre blir chifferteksten i utdataene. Denne typen angrep kalles KRIMINALITET.

Hvis du ikke har et vanskelig behov for å komprimere dataene, ikke komprimer dem.

Servermiljø

Som en generell regel bør du ikke være vert for sikkerhetssensitive applikasjoner på en delt server. For eksempel på delt hosting, der en motstander kan få tilgang til en virtuell maskin på samme fysiske server som deg.

Det er ulike grunner som gjør delte servere til et tvilsomt sted å være vert for sikkerhetskritiske applikasjoner. For eksempel har angrep mellom virtuelle servere nylig blitt demonstrert: eprint.iacr.org/2014/248.pdf. Dette er en god påminnelse om at offensive teknikker ikke degraderes, men snarere finpusses og forbedres over tid. Slike fallgruver må alltid tas i betraktning.

Ekspertkonsultasjon

Sist men ikke minst, ta kontakt med en ekspert for å gjennomgå sikkerhetskoden din.

(PHP 4, PHP 5, PHP 7)

krypt — Enveis strenghashing

Advarsel

Denne funksjonen er (ennå) ikke binærsikker!

Beskrivelse

krypt (streng $str [, streng $salt]): streng

krypt() vil returnere en hashet streng ved å bruke standard Unix DES-basert algoritme eller alternative algoritmer som kan være tilgjengelige på systemet.

Saltparameteren er valgfri. Derimot, krypt() skaper en svak hasj uten saltet. PHP 5.6 eller nyere gir en E_NOTICE-feil uten den. Sørg for å spesifisere et sterkt nok salt for bedre sikkerhet.

password_hash() bruker en sterk hash, genererer et sterkt salt og bruker riktige runder automatisk. password_hash() er en enkel krypt() wrapper og kompatibel med eksisterende passordhasher. Bruken av password_hash() oppmuntres.

Noen operativsystemer støtter mer enn én type hash. Noen ganger erstattes faktisk den standard DES-baserte algoritmen med en MD5-basert algoritme. Hash-typen utløses av salt-argumentet. Før 5.3 ville PHP bestemme de tilgjengelige algoritmene på installasjonstidspunktet basert på systemets krypt(). Hvis det ikke er gitt noe salt, vil PHP automatisk generere enten et standard to-tegns (DES) salt, eller et tolv tegn ( MD5), avhengig av tilgjengeligheten av MD5 crypt(). PHP setter en konstant navngitt CRYPT_SALT_LENGTH som indikerer det lengste gyldige saltet som er tillatt av de tilgjengelige hashene.

Standard DES-basert krypt() returnerer saltet som de to første tegnene i utdataene. Den bruker også bare de første åtte tegnene i str , så lengre strenger som starter med de samme åtte tegnene vil generere det samme resultatet (når det samme saltet brukes).

På systemer der crypt()-funksjonen støtter flere hash-typer, settes følgende konstanter til 0 eller 1 avhengig av om den gitte typen er tilgjengelig:

  • CRYPT_STD_DES- Standard DES-basert hash med et salt på to tegn fra alfabetet "./0-9A-Za-z". Bruk av ugyldige tegn i saltet vil føre til at crypt() mislykkes.
  • CRYPT_EXT_DES- Utvidet DES-basert hash. "Saltet" er en 9-tegns streng som består av en understrek etterfulgt av 4 byte med iterasjon og 4 byte salt. Disse er kodet som utskrivbare tegn, 6 biter per tegn, minst signifikante tegn først. Verdiene 0 til 63 er kodet som "./0-9A-Za-z". Bruk av ugyldige tegn i saltet vil føre til at crypt() mislykkes.
  • CRYPT_MD5- MD5 hashing med et salt på tolv tegn som starter med $1$
  • CRYPT_BLOWFISH- Blowfish hashing med et salt som følger: "$2a$", "$2x$" eller "$2y$", en tosifret kostnadsparameter, "$", og 22 tegn fra alfabetet "./0-9A- Za-z". Bruk av tegn utenfor dette området i saltet vil føre til at crypt() returnerer en null-lengde streng. Den tosifrede kostnadsparameteren er base-2-logaritmen til iterasjonsantallet for det underliggende Blowfish-baserte hashing-algoritmen og må være i området 04-31, verdier utenfor dette området vil føre til at crypt() mislykkes. Versjoner av PHP før 5.3.7 støtter kun "$2a$" som saltprefiks: PHP 5.3.7 introduserte de nye prefiksene for å fikse en sikkerhetssvakhet i Blowfish-implementeringen. Vennligst se for fullstendige detaljer om sikkerhetsfiksingen, men for å oppsummere bør utviklere som kun retter seg mot PHP 5.3.7 og nyere bruke "$2y$" fremfor "$2a$".
  • CRYPT_SHA256- SHA-256-hash med et salt på seksten tegn prefikset med $5$. Hvis saltstrengen starter med "runder=
  • CRYPT_SHA512- SHA-512-hash med et salt på seksten tegn prefikset med $6$. Hvis saltstrengen starter med "runder= $", brukes den numeriske verdien til N for å indikere hvor mange ganger hashing-løkken skal utføres, omtrent som kostnadsparameteren på Blowfish. Standard antall runder er 5000, det er minimum 1000 og maksimum 999.999.999. Ethvert utvalg av N utenfor dette området vil bli avkortet til nærmeste grense.

Fra og med PHP 5.3.0 inneholder PHP sin egen implementering og vil bruke den hvis systemet mangler støtte for en eller flere av algoritmene.

Parametere

Strengen som skal hashes.

Forsiktighet

Bruker CRYPT_BLOWFISH algoritme, vil resultere i at str-parameteren blir avkortet til en maksimal lengde på 72 tegn.

En valgfri saltstreng å basere hashing på. Hvis den ikke er gitt, er atferden definert av algoritmeimplementeringen og kan føre til uventede resultater.

Returverdier

Returnerer den hashed-strengen eller en streng som er kortere enn 13 tegn og er garantert forskjellig fra saltet ved feil.

Advarsel

Ved validering av passord bør en strengsammenligningsfunksjon som ikke er sårbar for timingangrep brukes for å sammenligne utdataene til krypt() til den tidligere kjente hasjen. PHP 5.6 og utover gir hash_equals() for dette formålet.

Endringslogg

Versjon Beskrivelse
5.6.5 Når feilstrengen "*0" er gitt som salt, vil "*1" nå bli returnert for samsvar med andre kryptimplementeringer. Før denne versjonen ville PHP 5.6 feilaktig returnere en DES-hash.
5.6.0 Hev E_NOTICE sikkerhetsadvarsel hvis salt er utelatt.
5.5.21 Når feilstrengen "*0" er gitt som salt, vil "*1" nå bli returnert for samsvar med andre kryptimplementeringer. Før denne versjonen ville PHP 5.5 (og tidligere grener) feilaktig returnere en DES-hash.
5.3.7 La til $2x$ og $2y$ Blowfish-moduser for å håndtere potensielle høybitangrep.
5.3.2 Lagt til SHA-256 og SHA-512 krypt basert på Ulrich Dreppers » implementering.
5.3.2 Fikset Blowfish-oppførsel på ugyldige runder for å returnere "failure"-streng ("*0" eller "*1"), i stedet for å falle tilbake til DES.
5.3.0 PHP inneholder nå sin egen implementering for MD5-krypten, Standard DES, Extended DES og Blowfish-algoritmene og vil bruke det hvis systemet mangler støtte for en eller flere av algoritmene.

Eksempler

Eksempel #1 krypt() eksempler

$hashed_password = krypt("mittpassord"); // la saltet genereres automatisk

/* Du bør sende hele resultatene til crypt() som saltet for å sammenligne en
passord, for å unngå problemer når forskjellige hashing-algoritmer brukes. (Som
det står ovenfor, standard DES-basert passordhashing bruker et 2-tegns salt,
men MD5-basert hashing bruker 12.) */
if (hash_equals ($hashed_password, crypt ($user_input, $hashed_password))) (
echo "Passord bekreftet!" ;
}
?>

Eksempel #2 ved å bruke krypt() med htpasswd

// Angi passordet
$password = "mittpassord" ;

// Få hashen, la saltet genereres automatisk
$hash = krypt($passord);
?>

Eksempel #3 ved å bruke krypt() med forskjellige hasjtyper

/* Disse saltene er kun eksempler, og skal ikke brukes ordrett i koden din.
Du bør generere et distinkt, riktig formatert salt for hvert passord.
*/
if (CRYPT_STD_DES == 1 ) (
ekko "Standard DES: " . krypt ("rasmuslerdorf", "rl") . "\n" ;
}

if (CRYPT_EXT_DES == 1 ) (
ekko "Utvidet DES: " . krypt ("rasmuslerdorf", "_J9..rasm") . "\n" ;
}

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

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

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

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

All informasjon kan krypteres eller dekrypteres, inkludert bruk av PHP. Dette språket har mange datakrypteringsmuligheter, fra enkelt til komplekst.

La oss se på de grunnleggende krypteringsmetodene

base64- lar deg kryptere og dekryptere data ved å bruke MIME base64-algoritmen. Den bruker ikke nøkler og brukes ofte til å skjule lenker i PHP.

Eksempler:
//krypter teksten
$text = "Link";
echo base64_encode($tekst); //Produserer: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==
//dekryptering
echo base64_decode("PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==");
?>

Som du kan se, brukte vi først base64_encode-operasjonen og fikk chifferen: PGEgaHJlZj0iIyI+0KHRgdGL0LvQutCwPC9hPg==, og deretter erstattet den med base64_decode og fikk koblingen tilbake.

md5- lar deg hash data ensidig. Det vil si at i motsetning til base64 vil du ikke lenger kunne dekryptere dem tilbake. Ofte brukes md5 til å lagre passord i en database, men nylig har den krypterte md5-kombinasjonen blitt lett å finne i dekrypteringstabeller, vennligst levert av mange nettsteder og algoritmer. Derfor, for å lagre md5-passord, er det bedre å erstatte algoritmer med Blowfish.

Eksempel:

//krypter teksten
echo md5("kombinasjon");
?>

Nøkkelkryptering

Og det siste eksemplet på kryptering/dekryptering som jeg ville snakke om bruker en nøkkel (som passord). Det vil si at du sender en unik nøkkel til krypteringsfunksjonen, og koden krypteres sammen med den. For å dekryptere må du gi funksjonen den krypterte koden og en nøkkel som bare du kjenner. Et eksempel på bruk av funksjoner helt nederst i koden.

funksjon __encode($tekst, $key) (



$enc_text=base64_encode(mcrypt_generic($td,$iv.$text));
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
returner $enc_text; ) )
funksjon strToHex($string) (
$hex="";
for ($i=0; $i< strlen($string); $i++) { $hex .= dechex(ord($string[$i])); }
returner $hex; )
funksjon __decode($tekst, $nøkkel) (
$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);
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);
returner $decode_text; ) )
funksjon hexToStr($hex) (
$string="";
for ($i=0; $i< strlen($hex)-1; $i+=2) { $string .= chr(hexdec($hex[$i].$hex[$i+1])); }
return $string; )

$str = "Buller som må krypteres!
Med nøkkel";
$code = strToHex(__encode($str, "My#key-do-36-simvolov"));
echo "Kryptert kode: ".$kode."
";

$str = __decode(hexToStr($code), "My#key-do-36-simvolov");
echo "Dekryptert kode: ".$str."
";
?>

Du kan kryptere html-innhold. Nøkkellengden må ikke være mer enn 36 tegn.

Denne metoden kan brukes til å kryptere noen data og plassere dem i en txt-fil eller database, og motta den ved hjelp av dekryptering med en nøkkel.

Selvfølgelig kan enhver kode dekrypteres/hackes og dette er intet unntak, så bruk sterke krypteringsmetoder.

En av de grunnleggende sannhetene til kryptografi er at du ikke bør finne opp noe på dette området med mindre du er en profesjonell. Dette er delvis sant, fordi alt det beste lenge har blitt oppfunnet, lidd og brukt i flere tiår innen informasjonsteknologi. Den andre siden av sannheten er at utviklingen av et visst kunnskapsfelt skjer bare med en konstant tilstrømning av friske ideer og originale løsninger i det.

Av åpenbare grunner vil vi ikke ta sikte på gigantene innen industriell kryptografi som AES, men stupe så å si inn i vår egen kryptografiske forskning med blackjack og glede.

Dels fordi det er interessant, dels fordi ved å modellere noe eget og sammenligne det med anerkjente standarder, ser du tydelig kontrasten, effektive løsninger og direkte utelatelser, og du forstår hva du kan strebe etter for å forbedre effektiviteten.

Men nok vann allerede.

La oss si at nettapplikasjonen vår er skrevet i PHP, trenger reversibel kryptering, og vi tror at vi kan skrive vårt eget chiffersystem.

Så la oss skrive vårt eget reversible krypteringssystem med private og offentlige nøkler, et som vil ha følgende funksjoner til en mer eller mindre sikker kryptografisk algoritme:

  1. Tilstedeværelsen av støysymboler i den endelige chifferen.
  2. Informasjon i hver avsender-destinasjonskanal vil bli kryptert med en privat nøkkel, og samsvarsfunksjonen vil være unik for hver nøkkel.
  3. Hver melding vil motta en sammendragskode – en unik kode som er en funksjon av den private nøkkelen og den opprinnelige meldingen. Dette er nødvendig for å oppnå unikhet til samsvarsfunksjonen "kildesymbol".<=>kodet symbol" ikke bare for "Sender-Receiver"-kanalen, men også for hver enkelt melding.

    Så selv om vi tenker oss at samsvaret mellom kodede og originale symboler for en bestemt melding har blitt kjent gjennom bruk av kryptografisk analyse, for eksempel frekvensanalyse, gir dette ingen preferanser når man studerer en annen melding.

  4. For å komplisere frekvensanalysen, vil vi kode hvert første meldingssymbol med to chiffersymboler.
Så hva skjedde.

Faktisk kan du se det endelige resultatet

SymCoder-klassen inkluderer kryptering og dekrypteringsmetoder.

Kryptering utføres av code()-metoden, som tar den opprinnelige meldingen som input.

Her lager en melding fra den genererte korrespondansetabellen i tab_coded en kryptert melding, fortynnet langs kantene og innvendig med støysymboler.

Støysymboler er forresten unike for hver sender-destinasjonskanal, siden de genereres ved hjelp av kanalnøkkelen, men ikke er unike for meldinger. Symbolene som brukes for kryptering i kode_symboler er noen skilletegn og symboler som %, @, etc.

For hvert kodet symbol er det to symboler fra kode_symboler, av åpenbare grunner at det er flere ganger færre av dem enn de kodede symbolene.

Create_tab_coded-korrespondansetabellen er bygget ved å bruke en oversettelse av meldingsnøkkelhashen til en matrise med antall elementer lik antallet elementer i kodesymbolmatrisen. Startposisjonen for å krysse to-tegns koder er også alltid forskjellig og er knyttet til kanalnøkkelen. Dette gjør det mulig å være sikker på at algoritmen for å krysse kodede symboler og matche kodesymboler til dem alltid (eller garantert ofte) vil være annerledes.

For eksempel ser "hello world"-meldingen, når den er kodet, slik ut:

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

Og her er den samme meldingen, kodet igjen:

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

Det kan sees at sammendraget av samme melding er det samme, men chifferen blir annerledes - støysymboler legges til i en vilkårlig match og i en vilkårlig rekkefølge for hver ny kryptering.

Meldinger har redundans, som avtar når volumet på meldingen øker, opptil 10 % støy (for de korteste meldingene når støyen 90 % eller høyere prosent), minimumslengden på en kryptert melding er 116 tegn. En av ulempene med denne krypteringsmetoden er at kodede meldinger minst dobles.

Dekoding består av omvendt oversettelse av formen "kodesymbol" - det originale symbolet med støy kuttet ut fra meldingen. Hva kan være nøkkelen? I utgangspunktet en hvilken som helst streng som er unik for hvert destinasjon-mottaker-par.

Hvis du for eksempel oppretter en messenger med meldingskryptering, kan den enkleste versjonen av den private nøkkelen være md5($user_id_1. $salt. $user_id_2), så vil nøkkelen være unik for hver meldingskanal.

La oss si at du må utveksle data mellom to servere. For å beskytte data mot avlytting av trafikk er dataene kryptert. Vel, for eksempel overføring av handlinger innenfor et botnett. Dette er det som i hovedsak ikke er kryptering, men som kalles koding, og det brukes velkjente funksjoner for å dekode slik kode.

Som et annet eksempel på pseudo-kryptering, vil jeg gi et eksempel på "kryptering" av passord i databasen til ett CMS - der passord er ikke kryptert i md5() eller , men bare kodet via base64. De. Når databasen lekkes, vil det ikke være vanskelig for en hacker å dekryptere alle passord ved hjelp av den innebygde PHP-funksjonen base64_decode().

Vi må overføre data uten å bekymre oss for at noen skal kunne fange opp teksten og dekryptere den. PHP har en populær datakrypteringspakke kalt Mcrypt, som gir toveis kryptering (det vil si selve kryptering og dekryptering av data).

Mcrypt versjon 2.4.7 støtter følgende symmetriske krypteringsalgoritmer: Blowfish, RC2, Safer-sk64 xtea, Cast-256, RC4, Safer-sk128, DES, RC4-iv, Serpent, Enigma, Rijndael-128, Threeway, Rijndael-192 , TripleDES, LOKI97, Rijndael-256, Twofish, Panama, Saferplus, etc. Flere detaljer om hver algoritme er skrevet på Wikipedia.

Siden symmetrisk kryptering brukes, må nøkkelen være kjent for begge parter og holdes hemmelig.

Eksempel på kryptering og dekryptering av en streng

mcrypt_module_open("des", "", "ecb", "")
Denne funksjonen åpner algoritmemodulen og modusen som brukes. For dette eksemplet er DES-algoritmen i ECB-modus.

$nøkkel = substr($nøkkel, 0, mcrypt_enc_get_key_size($td));
Maksimal nøkkelstørrelse må oppnås ved å kalle opp mcrypt_enc_get_key_size()-funksjonen, og enhver verdi mindre enn dette vil være korrekt.

$s = mcrypt_generic($td, $kilde);
Ved kryptering blir dataene polstret med null byte for å sikre at dataene er n*blokkstørrelse lange. Blokkstørrelsen av blokkstørrelsen bestemmes av algoritmen (for DES er blokkstørrelsen 64 biter). Derfor, ved dekryptering, kan "\0" vises på slutten av linjen, som fjernes av trim()-funksjonen