sql >> Database teknologi >  >> RDS >> Mysql

Laravel AES-256 Encryption &MySQL

Opdater

PR 31721 er blevet flettet ind i Laravel 7.0.8, som retter de undslupne skråstreger i json-kodningen. Før dette ville kryptering af de samme data give dig resultater med variabel størrelse. Nu, fra 7.0.8, vil kryptering af de samme data give dig samme størrelsesresultat hver gang.

TL;DR:

Laravels krypteringsmetode returnerer en streng, så datatypen skal være en varchar- eller tekstvariation, afhængigt af størrelsen på de data, der krypteres.

For at bestemme den omtrentlige størrelse kan du bruge følgende række af beregninger:

Laravel>=7.0.8

Lad a =størrelsen af ​​de serialiserede ukrypterede data (strlen(serialize($data)) )
Lad b =a + 16 - (a MOD 16) (beregn størrelsen af ​​krypterede data)
Lad c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (beregn størrelsen af ​​base64-kodede data)
Lad d =c + 117 (tilføj størrelse på MAC, IV og json-kodning)
Lad e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (beregn størrelsen af ​​base64-kodede data)

Selvom værdien ikke er deterministisk, er størrelsen af ​​resultatet det. Hvis du f.eks. skulle kryptere et 9-cifret personnummer, vil resultatet altid være 216 tegn.

Laravel <7.0.8

Lad a =størrelsen af ​​de serialiserede ukrypterede data (strlen(serialize($data)) )
Lad b =a + 16 - (a MOD 16) (beregn størrelsen af ​​krypterede data)
Lad c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (beregn størrelsen af ​​base64-kodede data)
Lad d =c + 117 + 8 + ((c + 2 - ((c + 2) MOD 3)) / 3) (tilføj størrelse på MAC, IV og json-kodning, plus ekstra buffer til potentielt undslippede skråstreger)
Lad e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (beregn størrelsen af ​​base64-kodede data)

Hvis du f.eks. skulle kryptere et 9-cifret personnummer, ville resultatet være på minimum 216 tegn og højst 308 tegn (selvom dette sandsynligvis er en statistisk umulighed). Hvis du kører en løkke på 100.000+ krypteringer, vil du se, at størrelsen normalt er i intervallet 216 - 224. Formlen ovenfor ville fortælle dig at indstille dit felt til 248 tegn, hvilket er en sund buffer over det forventede interval, men ikke statistisk umuligt at ramme.

Detaljer:

Den værdi, der returneres fra krypteringsmetoden, er ikke kun den krypterede tekst, men er en base64-kodet repræsentation af et json-kodet nyttelastarray, der indeholder (1) den base64-kodede krypterede værdi af de serialiserede data, (2) den base64-kodede initialiseringsvektor ( IV), og (3) meddelelsesgodkendelseskoden (MAC). Så for at bestemme størrelsen på det nødvendige felt, skal du kende den maksimale størrelse af de data, der vil blive kodet, og derefter tilføje noget ekstra plads til disse ekstra stykker information, der er fyldt i den returnerede streng.

Lad os først beregne den maksimale størrelse af din krypterede værdi. Da din krypteringsalgoritme (AES-256-CBC) er en blokchiffer, gøres dette ret nemt med en formel. AES bruger 16 byte blokke og kræver mindst én byte af udfyldning, så størrelsen af ​​den krypterede værdi vil være det næste multiplum af 16. Så hvis dine originale data er 30 bytes, vil dine krypterede data være 32 bytes. Hvis dine originale data er 32 bytes, vil dine krypterede data være 48 bytes (da AES kræver mindst én byte af polstring, bliver dine 32 bytes 33, og så går det op til det næste multiplum af 16 til 48). Formlen for dette ville være x + 16 - (x MOD 16) . Så for 30 bytes får du 30 + 16 - (30 MOD 16) = 32 .

Når du beregner størrelsen af ​​den krypterede værdi, skal du huske på, at de data, der krypteres, først serialiseres. Så hvis du for eksempel krypterer et personnummer, er den almindelige værdi kun 9 tegn, men den serialiserede værdi er faktisk 16 tegn (s:9:"xxxxxxxxx"; ). Da den serialiserede værdi er det, der faktisk er krypteret, og den er 16 bytes, vil størrelsen af ​​den krypterede værdi være 32 bytes (16 + 16 - (16 MOD 16) = 32 ).

Ud over dette er openssl_encrypt funktion returnerer de krypterede data, der allerede er base64-kodet. Base64-kodning øger størrelsen af ​​værdien med omkring 4/3. For hver 3 bytes i de originale data vil base64-kodning generere en 4 byte (tegn) repræsentation. Så for SSN-eksemplet er det krypterede resultat 32 bytes. Ved oversættelse til base64 giver 32 bytes os (32 / 3) = 10.6 3 byte segmenter. Da base64 skifter til den næste byte, tag loftet og gange med 4, hvilket giver 11 * 4 = 44 bytes. Så vores originale 32 byte krypterede værdi bliver en streng på 44 tegn. Hvis du har brug for en formel til dette, kan du bruge (x + 2 - ((x + 2) MOD 3)) / 3 * 4 . Så (32 + 2 - ((32 + 2) MOD 3)) / 3 * 4 = 44 .

Den næste oplysning er MAC. MAC'en er en SHA256 hashed værdi, så vi ved, at den vil være på 64 tegn.

Den sidste oplysning er IV. Den almindelige IV er 16 tilfældige bytes. IV'en, der er gemt i nyttelast-arrayet, er den base64-kodede værdi af den almindelige IV. Så vi kan bruge formlen ovenfor til at beregne størrelsen af ​​den base64-kodede IV:(16 + 2 - ((16 + 2) MOD 3)) / 3 * 4 = 24 .

Disse tre stykker information komprimeres til et array og derefter json_encoded. På grund af json-repræsentationen og navnet på værdierne i arrayet tilføjer dette yderligere 29 bytes.

Derudover, i Laravel <7.0.8, escapes eventuelle skråstreger i de base64-kodede data med omvendte skråstreger i json-strengen, så dette tilføjer et variabelt antal bytes afhængigt af hvor mange skråstreger der er til stede. For SSN-eksemplet er der 68 tegn base64-kodede data (44 for krypterede data, 24 for IV). Lad os antage, at det maksimale antal skråstreger sandsynligvis er omkring 1/3 af resultaterne, eller omkring 23 ekstra bytes. I Laravel>=7.0.8 undslippes disse skråstreger ikke, så der er ingen ekstra bytes.

Endelig er denne json_encoded værdi base64_encoded, hvilket igen vil øge størrelsen med en faktor på omkring 4/3.

Så for at sætte det hele sammen, lad os igen forestille os, at du krypterer et personnummer. openssl_encrypt resultatet vil være 44 tegn, MAC'en er 64 tegn, IV'en er 24 tegn, og json-repræsentationen tilføjer yderligere 29 tegn.

I Laravel <7.0.8 er der også bufferen på yderligere 23 tegn. Dette giver os (44 + 64 + 24 + 29 + 23 = 184 ) tegn. Dette resultat bliver base64-kodet, hvilket giver os ((184 + 2 - ((184 + 2) MOD 3)) / 3 * 4 = 248 ) tegn.

I Laravel>=7.0.8 er der ingen ekstra buffer. Dette giver os (44 + 64 + 24 + 29 = 161 ) tegn. Dette resultat bliver base64-kodet, hvilket giver os ((161 + 2 - ((161 + 2) MOD 3)) / 3 * 4 = 216 ) tegn.



  1. Samlet funktion i MySQL - liste (som LISTAGG i Oracle)

  2. Bedste praksis:Importer mySQL-fil i PHP; opdelt forespørgsler

  3. ved hjælp af MySql.Data.MySqlClient; Det virker ikke

  4. php imap - få brødtekst og lav almindelig tekst