sql >> Databáze >  >> RDS >> Mysql

Laravel AES-256 šifrování a MySQL

Aktualizovat

PR 31721 byl začleněn do Laravel 7.0.8, který opravuje uniklá lomítka v kódování json. Předtím by šifrování stejných dat poskytlo výsledky s proměnlivou velikostí. Nyní, od 7.0.8, vám šifrování stejných dat poskytne pokaždé stejně velký výsledek.

TL;DR:

Laravelova metoda šifrování vrátí řetězec, takže datový typ by měl být varchar nebo textová varianta, v závislosti na velikosti šifrovaných dat.

Chcete-li určit přibližnou velikost, můžete použít následující řadu výpočtů:

Laravel>=7.0.8

Nechat a =velikost serializovaných nešifrovaných dat (strlen(serialize($data)) )
Nechť b =a + 16 - (a MOD 16) (vypočítejte velikost zašifrovaných dat)
Nechte c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (vypočítejte velikost dat kódovaných base64)
Nechť d =c + 117 (přidejte velikost kódování MAC, IV a json)
Nechte e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (vypočítejte velikost dat kódovaných base64)

I když hodnota není deterministická, velikost výsledku ano. Pokud byste například zašifrovali 9místné číslo sociálního pojištění, výsledek bude mít vždy 216 znaků.

Laravel <7.0.8

Nechat a =velikost serializovaných nešifrovaných dat (strlen(serialize($data)) )
Nechť b =a + 16 - (a MOD 16) (vypočítejte velikost zašifrovaných dat)
Nechte c =(b + 2 - ((b + 2) MOD 3)) / 3 * 4 (vypočítejte velikost dat kódovaných base64)
Nechť d =c + 117 + 8 + ((c + 2 - ((c + 2) MOD 3)) / 3) (přidejte velikost kódování MAC, IV a json plus další vyrovnávací paměť pro potenciálně escapovaná lomítka)
Nechte e =(d + 2 - ((d + 2) MOD 3)) / 3 * 4 (vypočítejte velikost dat kódovaných base64)

Pokud byste například zašifrovali 9místné číslo sociálního zabezpečení, výsledek by měl minimálně 216 znaků a maximálně 308 znaků (i když je to pravděpodobně statisticky nemožné). Pokud spustíte smyčku 100 000+ šifrování, uvidíte, že velikost je obvykle v rozsahu 216 - 224. Výše uvedený vzorec by vám řekl, že máte pole nastavit na 248 znaků, což je zdravá vyrovnávací paměť nad očekávaným rozsahem, ale není statisticky nemožné se trefit.

Podrobnosti:

Hodnota vrácená z metody šifrování není pouze zašifrovaný text, ale je to zakódovaná reprezentace pole užitečného zatížení zakódovaného ve formátu json, které obsahuje (1) zašifrovanou hodnotu serializovaných dat zakódovanou v base64, (2) inicializační vektor zakódovaný v base64 ( IV) a (3) ověřovací kód zprávy (MAC). Chcete-li tedy určit velikost potřebného pole, budete muset znát maximální velikost dat, která budou zakódována, a poté přidat další prostor pro tyto dodatečné informace, které jsou nacpány ve vráceném řetězci.

Nejprve spočítejme maximální velikost vaší šifrované hodnoty. Protože váš šifrovací algoritmus (AES-256-CBC) je bloková šifra, lze to docela snadno provést pomocí vzorce. AES používá 16bajtové bloky a vyžaduje alespoň jeden bajt výplně, takže velikost zašifrované hodnoty bude nejbližší násobek 16. Pokud tedy mají vaše původní data 30 bajtů, budou mít vaše šifrovaná data 32 bajtů. Pokud jsou vaše původní data 32 bajtů, vaše zašifrovaná data budou mít 48 bajtů (protože AES vyžaduje alespoň jeden bajt výplně, z vašich 32 bajtů se stane 33, a to se zvýší na další násobek 16 až 48). Vzorec by byl x + 16 - (x MOD 16) . Takže za 30 bajtů získáte 30 + 16 - (30 MOD 16) = 32 .

Při výpočtu velikosti zašifrované hodnoty mějte na paměti, že šifrovaná data jsou nejprve serializována. Pokud tedy například šifrujete rodné číslo, obyčejná hodnota je pouze 9 znaků, ale serializovaná hodnota je ve skutečnosti 16 znaků (s:9:"xxxxxxxxx"; ). Protože serializovaná hodnota je to, co je skutečně zašifrováno, a má 16 bajtů, bude velikost zašifrované hodnoty 32 bajtů (16 + 16 - (16 MOD 16) = 32 ).

Kromě toho openssl_encrypt funkce vrací zašifrovaná data již zakódovaná base64. Kódování Base64 zvětší velikost hodnoty asi o 4/3. Pro každé 3 bajty v původních datech vygeneruje kódování base64 4 bajtovou (znakovou) reprezentaci. Takže pro příklad SSN je zašifrovaný výsledek 32 bajtů. Při překladu do base64 nám 32 bajtů dává (32 / 3) = 10.6 3 byte segmenty. Vzhledem k tomu, že base64 přechází na další bajt, vezměte strop a vynásobte 4, což dává 11 * 4 = 44 bajtů. Naše původní 32bajtová zašifrovaná hodnota se tedy stane 44znakovým řetězcem. Pokud k tomu potřebujete vzorec, můžete použít (x + 2 - ((x + 2) MOD 3)) / 3 * 4 . Takže (32 + 2 - ((32 + 2) MOD 3)) / 3 * 4 = 44 .

Další informací je MAC. MAC je hašovaná hodnota SHA256, takže víme, že bude mít 64 znaků.

Poslední informací je IV. Prostý IV má 16 náhodných bajtů. IV uložená v poli užitečného zatížení je zakódovaná hodnota plain IV. Můžeme tedy použít výše uvedený vzorec k výpočtu velikosti IV kódovaného base64:(16 + 2 - ((16 + 2) MOD 3)) / 3 * 4 = 24 .

Tyto tři informace jsou zkomprimovány do pole a poté zakódovány json_encode. Kvůli reprezentaci json a názvu hodnot v poli to přidává dalších 29 bajtů.

Navíc v Laravel <7.0.8 jsou všechna dopředná lomítka v datech kódovaných base64 escapována zpětnými lomítky v řetězci json, takže to přidává proměnný počet bajtů v závislosti na tom, kolik lomítek je přítomno. Pro příklad SSN existuje 68 znaků kódovaných dat base64 (44 pro zašifrovaná data, 24 pro IV). Předpokládejme, že maximální počet lomítek je pravděpodobně asi 1/3 výsledků nebo asi 23 bajtů navíc. V Laravelu>=7.0.8 nejsou tato lomítka escapována, takže nejsou žádné bajty navíc.

A konečně, tato hodnota json_encoded je base64_encoded, což opět zvýší velikost přibližně 4/3.

Abychom to dali dohromady, znovu si představme, že šifrujete číslo sociálního pojištění. openssl_encrypt výsledek bude 44 znaků, MAC je 64 znaků, IV je 24 znaků a reprezentace json přidá dalších 29 znaků.

V Laravel <7.0.8 je také vyrovnávací paměť 23 znaků navíc. To nám dává (44 + 64 + 24 + 29 + 23 = 184 ) znaky. Tento výsledek je zakódován base64, což nám dává ((184 + 2 - ((184 + 2) MOD 3)) / 3 * 4 = 248 ) znaky.

V Laravelu>=7.0.8 není žádný další buffer. To nám dává (44 + 64 + 24 + 29 = 161 ) znaky. Tento výsledek je zakódován base64, což nám dává ((161 + 2 - ((161 + 2) MOD 3)) / 3 * 4 = 216 ) znaky.



  1. Okamžitá inicializace souboru:Dopad během instalace

  2. Odstranění duplicitních řádků z tabulky

  3. AOL/J Setup Testovací sada

  4. Problém s PDO bindParam