Versleuteling in MySQL: de hoofdsleutel gebruiken

In afwachting van de start van een nieuwe inschrijving voor de opleiding "Database" we blijven een reeks artikelen publiceren over encryptie in MySQL.

Versleuteling in MySQL: de hoofdsleutel gebruiken

In het vorige artikel in deze reeks (Encryptie in MySQL: Keystore) hadden we het over het bewaren van sleutels. In dit artikel bespreken we hoe de hoofdsleutel wordt gebruikt en de voor- en nadelen van enveloppe-encryptie. 

Het idee achter envelopversleuteling is dat de sleutels die voor de versleuteling worden gebruikt (tabelruimtesleutels) worden versleuteld met een andere sleutel (de hoofdsleutel). Tabelruimtesleutels worden feitelijk gebruikt om gegevens te versleutelen. Grafisch kan dit als volgt worden weergegeven:

Versleuteling in MySQL: de hoofdsleutel gebruiken

De hoofdsleutel bevindt zich in de sleutelbos en de sleutels van de tabelruimte bevinden zich in de gecodeerde tabelruimteheaders (op pagina 0 van de tabelruimte). 

Op de foto hierboven:

  • Tabel A is gecodeerd met sleutel 1 (Sleutel 1). Sleutel 1 wordt gecodeerd met de hoofdsleutel en in gecodeerde vorm opgeslagen in de header van tabel A.

  • Tabel B is gecodeerd met sleutel 2. Sleutel 2 is gecodeerd met behulp van de maskersleutel en in gecodeerde vorm opgeslagen in de header van tabel B.

  • En ga zo maar door.

Wanneer de server tabel A moet decoderen, haalt hij de hoofdsleutel op uit de opslag, leest hij de gecodeerde sleutel 1 uit de header van tabel A en decodeert hij sleutel 1. De gedecodeerde sleutel 1 wordt in het geheugen van de server opgeslagen en gebruikt om tabel A te decoderen.

InnoDB

Bij InnoDB vindt de daadwerkelijke encryptie en decryptie plaats op I/O-niveau. Dat wil zeggen dat de pagina wordt gecodeerd vlak voordat deze naar de schijf wordt geschreven, en wordt gedecodeerd vlak nadat deze van de schijf is gelezen.

In InnoDB werkt encryptie alleen op tabelruimteniveau. En standaard worden alle tabellen in afzonderlijke tabelruimten gemaakt (bestand-per-tabel tabelruimte). Met andere woorden: er wordt een tabelruimte gemaakt die slechts één tabel kan bevatten. Hoewel u ook tabellen in de primaire tabelruimte kunt maken (algemene tabelruimte). Maar in ieder geval bevindt de tabel zich altijd in een bepaalde tabelruimte. En omdat de encryptie op het niveau van de tabelruimte plaatsvindt, is er sprake van volledige encryptie of niet. Dat wil zeggen dat het niet mogelijk is om slechts een deel van de tabellen in de hoofdtabelruimte te versleutelen. 

Als u om een ​​of andere reden bestand-per-tabel hebt uitgeschakeld, worden alle tabellen in de systeemtabelruimte gemaakt. IN Percona-server voor MySQL U kunt de systeemtabelruimte versleutelen met behulp van de variabele innodbsystabelruimteversleutelen of encryptiethreads gebruiken, maar dit is nog steeds een experimentele functie. MySQL heeft dit niet.

Voordat we verder gaan, moeten we de structuur van de hoofdsleutel-ID bekijken. Het bestaat uit UUID, KEYID en prefix "INNODBKey". Het ziet er zo uit: INNODBKey-UUID-KEYID.

UUID is de uuid van de server met de gecodeerde tabelruimte. SLEUTELDe ID is eenvoudigweg een voortdurend toenemende waarde. Wanneer de hoofdsleutel KEY voor het eerst wordt aangemaaktID is 1. Tijdens de sleutelrotatie, wanneer een nieuwe hoofdsleutel wordt aangemaakt, KEYID = 2 enzovoort. In de volgende artikelen uit deze serie gaan we dieper in op het roteren van hoofdsleutels.

Nu we weten hoe de hoofdsleutel-identificatie eruitziet, kunnen we naar de versleutelde tabelruimteheader kijken. Wanneer een tabelruimte wordt gecodeerd, wordt er coderingsinformatie aan de header toegevoegd. Het ziet er zo uit:

Versleuteling in MySQL: de hoofdsleutel gebruiken

SLEUTEL-ID is SLEUTELID van de hoofdsleutelidentificatie die we al besproken hebben. UUID is de uuid van de server, die ook wordt gebruikt in de hoofdsleutel-id. TABLESPACE KEY - een tabelruimtesleutel die bestaat uit 256 bits die willekeurig door de server worden gegenereerd. De initialisatievector (IV) bestaat ook uit 256 willekeurig gegenereerde bits (hoewel dit er 128 zouden moeten zijn). IV wordt gebruikt om AES-encryptie en -decryptie te initialiseren (slechts 256 van de 128 bits worden gebruikt). Aan het einde is er een CRC32-controlesom voor de TABLESPACE KEY en IV.

Ik heb het steeds een beetje simpel gehouden door te zeggen dat de header een gecodeerde sleutel voor de tabelruimte bevat. De sleutel van de tabelruimte en de IV worden feitelijk samen opgeslagen en gecodeerd met behulp van de hoofdsleutel. Houd er rekening mee dat er een CRC32 voor de sleutel en IV van de tabelruimte wordt berekend voordat deze worden gecodeerd.

Waarom hebben we CRC32 nodig?

Kortom, om de geldigheid van de hoofdsleutel te garanderen. Nadat de sleutel van de tabelruimte en IV zijn gedecodeerd, wordt de controlesom berekend en vergeleken met de CRC32 die in de header is opgeslagen. Als de controlesommen overeenkomen, hebben we de juiste hoofdsleutel en tablespacesleutel. Anders wordt de tabelruimte als ontbrekend gemarkeerd (we kunnen deze toch niet decoderen).

U vraagt ​​zich misschien af: wanneer worden de sleutels gecontroleerd? Het antwoord is wanneer de server start. Server met gecodeerde tabellen/tabelruimten leest UUID en KEY bij het opstartenID uit de header en genereert de hoofdsleutel-identificatie. Vervolgens haalt het de vereiste hoofdsleutel uit de sleutelbos, ontcijfert de sleutel van de tabelruimte en verifieert de controlesom. Als de controlesom overeenkomt, is er niets aan de hand. Als dat niet het geval is, wordt de tabelruimte als ontbrekend gemarkeerd.

Als u het vorige artikel in deze serie hebt gelezen (Encryptie in MySQL: Keystore), dan herinnert u zich misschien dat bij gebruik van een server-side keystore de server bij het opstarten alleen een lijst met sleutel-ID's ontvangt, of preciezer, de sleutel-ID en gebruikers-ID, omdat dit paar de sleutel eenduidig ​​identificeert. Ik zeg nu dat de server bij het opstarten alle sleutels ontvangt die nodig zijn om te testen of de sleutels van de tabelruimte kunnen worden ontsleuteld. Waarom worden bij het initialiseren van serveropslag alleen de sleutels geladen?id en gebruikerid, en niet alle sleutels? Omdat u mogelijk niet alle sleutels nodig hebt. Dit komt hoofdzakelijk door de rotatie van de hoofdsleutel. Wanneer u een hoofdsleutel roteert, wordt er een nieuwe hoofdsleutel in de opslagplaats gemaakt. Oude sleutels worden echter niet verwijderd. Het kan dus zo zijn dat er in uw server-keystore veel sleutels staan ​​die de server niet nodig heeft en die daarom niet worden opgehaald wanneer de server start.

Het is tijd om het een beetje te hebben over de voor- en nadelen van encryptie met hoofdsleutel. Het grootste voordeel is dat u slechts één encryptiesleutel nodig hebt (de hoofdsleutel). Deze wordt apart van uw versleutelde gegevens opgeslagen. Hierdoor verloopt het opstarten van de server snel en is de opslagruimte klein, waardoor deze gemakkelijker te beheren is. En ook de enkele hoofdsleutel is eenvoudig te regenereren.

Versleuteling met een hoofdsleutel heeft echter één groot nadeel: als een tablespace eenmaal is versleuteld met tablespace_key, blijft deze altijd versleuteld met dezelfde sleutel. Het draaien van de hoofdsleutel heeft hier geen zin. Waarom is dit een nadeel? We weten dat MySQL bugs bevat waardoor de software plotseling kan crashen en er een kernbestand kan worden aangemaakt. Omdat het kernbestand een geheugendump van de server bevat, kan het voorkomen dat de dump een ontsleutelde tabelruimtesleutel bevat. Om het nog erger te maken, worden ontsleutelde sleutels van tabelruimten in het geheugen opgeslagen. Deze sleutels kunnen vervolgens naar schijf worden overgezet. Je zou kunnen zeggen dat dit geen nadeel is omdat je root-toegang nodig hebt om toegang te krijgen tot deze bestanden en de swap-partitie. Ja. Maar root is slechts tijdelijk nodig. Zodra iemand toegang heeft tot de ontsleutelde sleutel van de tabelruimte, kan hij/zij deze blijven gebruiken om gegevens te ontsleutelen, zelfs zonder root-rechten. Daarnaast kan de schijf worden gestolen en kunnen de swap-partitie-/kernbestanden worden gelezen met behulp van hulpprogramma's van derden. Het doel van TDE is om de schijf onleesbaar te maken, zelfs als deze wordt gestolen. IN Percona-server voor MySQL Het is mogelijk om de tabelruimte opnieuw te versleutelen met nieuwe sleutels. Deze functie heet encryptiethreads en is op het moment van schrijven nog experimenteel.

Lees meer over de cursus

Lees verder:

Bron: www.habr.com