sql >> Database >  >> RDS >> Mysql

Laravel AES-256-codering en MySQL

Bijwerken

PR 31721 is samengevoegd met Laravel 7.0.8, dat de escaped forward slashes in de json-codering corrigeert. Voordien zou het versleutelen van dezelfde gegevens u resultaten van variabele grootte opleveren. Nu, vanaf 7.0.8, geeft het versleutelen van dezelfde gegevens je elke keer hetzelfde resultaat.

TL;DR:

De versleutelingsmethode van Laravel retourneert een tekenreeks, dus het gegevenstype moet een varchar- of tekstvariatie zijn, afhankelijk van de grootte van de gegevens die worden versleuteld.

Om de geschatte grootte te bepalen, kunt u de volgende reeks berekeningen gebruiken:

Laravel>=7.0.8

Laat a =de grootte van de geserialiseerde niet-versleutelde gegevens (strlen(serialize($data)) )
Laat b =a + 16 - (a MOD 16) (bereken de grootte van versleutelde gegevens)
Laat c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (bereken de grootte van met base64 gecodeerde gegevens)
Laat d =c + 117 (voeg grootte toe van MAC-, IV- en json-codering)
Laat e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (bereken de grootte van met base64 gecodeerde gegevens)

Hoewel de waarde niet deterministisch is, is de grootte van het resultaat dat wel. Als u bijvoorbeeld een 9-cijferig burgerservicenummer zou coderen, is het resultaat altijd 216 tekens.

Laravel <7.0.8

Laat a =de grootte van de geserialiseerde niet-versleutelde gegevens (strlen(serialize($data)) )
Laat b =a + 16 - (a MOD 16) (bereken de grootte van versleutelde gegevens)
Laat c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (bereken de grootte van met base64 gecodeerde gegevens)
Laat d =c + 117 + 8 + ((c + 2 - ((c + 2) MOD 3)) / 3) (voeg grootte toe van MAC-, IV- en json-codering, plus extra buffer voor mogelijk ontsnapte slashes)
Laat e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (bereken de grootte van met base64 gecodeerde gegevens)

Als u bijvoorbeeld een 9-cijferig burgerservicenummer zou coderen, zou het resultaat minimaal 216 tekens en maximaal 308 tekens zijn (hoewel dit waarschijnlijk een statistische onmogelijkheid is). Als u een lus van meer dan 100.000 versleutelingen uitvoert, ziet u dat de grootte meestal tussen 216 en 224 ligt. De bovenstaande formule zou u vertellen om uw veld in te stellen op 248 tekens, wat een gezonde buffer is boven het verwachte bereik, maar statistisch gezien niet onmogelijk om te bereiken.

Details:

De waarde die wordt geretourneerd door de versleutelingsmethode is niet alleen de versleutelde tekst, maar is een met base64 gecodeerde weergave van een json-gecodeerde payload-array die (1) de met base64 gecodeerde versleutelde waarde van de geserialiseerde gegevens bevat, (2) de met base64 gecodeerde initialisatievector ( IV), en (3) de berichtauthenticatiecode (MAC). Dus, om de grootte van het benodigde veld te bepalen, moet je de maximale grootte weten van de gegevens die zullen worden gecodeerd, en dan wat extra ruimte toevoegen voor deze extra stukjes informatie die in de geretourneerde string worden gestopt.

Laten we eerst de maximale grootte van uw versleutelde waarde berekenen. Aangezien uw coderingsalgoritme (AES-256-CBC) een blokcijfer is, is dit vrij eenvoudig te doen met een formule. AES gebruikt blokken van 16 bytes en vereist ten minste één byte opvulling, dus de grootte van de versleutelde waarde is het volgende veelvoud van 16. Dus als uw oorspronkelijke gegevens 30 bytes zijn, zijn uw versleutelde gegevens 32 bytes. Als uw oorspronkelijke gegevens 32 bytes zijn, zijn uw versleutelde gegevens 48 bytes (aangezien AES ten minste één byte opvulling vereist, wordt uw 32 bytes 33, en dan gaat dat omhoog naar het volgende veelvoud van 16 tot 48). De formule hiervoor is x + 16 - (x MOD 16) . Dus voor 30 bytes krijg je 30 + 16 - (30 MOD 16) = 32 .

Houd er bij het berekenen van de grootte van de versleutelde waarde rekening mee dat de gegevens die worden versleuteld eerst worden geserialiseerd. Als u bijvoorbeeld een burgerservicenummer versleutelt, is de normale waarde slechts 9 tekens, maar de geserialiseerde waarde is in werkelijkheid 16 tekens (s:9:"xxxxxxxxx"; ). Aangezien de geserialiseerde waarde is wat feitelijk is versleuteld, en het is 16 bytes, zal de grootte van de versleutelde waarde 32 bytes zijn (16 + 16 - (16 MOD 16) = 32 ).

Daarnaast is de openssl_encrypt functie retourneert de gecodeerde gegevens die al in base64 zijn gecodeerd. Base64-codering vergroot de waarde met ongeveer 4/3. Voor elke 3 bytes in de originele gegevens genereert base64-codering een representatie van 4 bytes (tekens). Dus voor het SSN-voorbeeld is het versleutelde resultaat 32 bytes. Bij het vertalen naar base64, geeft 32 bytes ons (32 / 3) = 10.6 3 bytes segmenten. Aangezien base64 naar de volgende byte gaat, neemt u het plafond en vermenigvuldigt u dit met 4, wat 11 * 4 = 44 geeft bytes. Dus onze oorspronkelijke 32 byte versleutelde waarde wordt een reeks van 44 tekens. Als je hier een formule voor nodig hebt, kun je (x + 2 - ((x + 2) MOD 3)) / 3 * 4 gebruiken . Dus, (32 + 2 - ((32 + 2) MOD 3)) / 3 * 4 = 44 .

Het volgende stukje informatie is de MAC. De MAC is een gehashte SHA256-waarde, dus we weten dat het 64 tekens zal zijn.

Het laatste stukje informatie is de IV. De gewone IV is 16 willekeurige bytes. De IV die is opgeslagen in de payload-array is de base64-gecodeerde waarde van de gewone IV. We kunnen dus de bovenstaande formule gebruiken om de grootte van de met base64 gecodeerde IV te berekenen:(16 + 2 - ((16 + 2) MOD 3)) / 3 * 4 = 24 .

Deze drie stukjes informatie worden gecomprimeerd tot een array en vervolgens json_encoded. Vanwege de json-representatie en de naam van de waarden in de array, voegt dit nog eens 29 bytes toe.

Bovendien worden in Laravel <7.0.8 alle slashes in de base64-gecodeerde gegevens geëscaped met backslashes in de json-tekenreeks, dus dit voegt een variabel aantal bytes toe, afhankelijk van hoeveel slashes er aanwezig zijn. Voor het SSN-voorbeeld zijn er 68 tekens met base64-gecodeerde gegevens (44 voor de versleutelde gegevens, 24 voor de IV). Laten we aannemen dat het maximale aantal slashes waarschijnlijk ongeveer 1/3 van de resultaten is, of ongeveer 23 extra bytes. In Laravel>=7.0.8 zijn deze slashes niet ontsnapt, dus er zijn geen extra bytes.

Ten slotte is deze json_encoded-waarde base64_encoded, wat de grootte opnieuw met een factor van ongeveer 4/3 zal vergroten.

Dus, om dit allemaal samen te voegen, laten we ons opnieuw voorstellen dat u een burgerservicenummer versleutelt. De openssl_encrypt het resultaat is 44 tekens, de MAC is 64 tekens, de IV is 24 tekens en de json-representatie voegt nog eens 29 tekens toe.

In Laravel <7.0.8 is er ook de buffer van 23 extra tekens. Dit geeft ons (44 + 64 + 24 + 29 + 23 = 184 ) tekens. Dit resultaat wordt met base64 gecodeerd, wat ons ((184 + 2 - ((184 + 2) MOD 3)) / 3 * 4 = 248 geeft ) tekens.

In Laravel>=7.0.8 is er geen extra buffer. Dit geeft ons (44 + 64 + 24 + 29 = 161 ) tekens. Dit resultaat wordt met base64 gecodeerd, wat ons geeft ((161 + 2 - ((161 + 2) MOD 3)) / 3 * 4 = 216 ) tekens.



  1. Psycopg2 Invoegen in tabel met tijdelijke aanduidingen

  2. postgresql COUNT (DISTINCT ...) erg traag

  3. Doe mee met de PAUG Database Designer Conference

  4. decimaal(s,p) of getal(s,p)?