Kryptering i MySQL: bruk av Hovednøkkel

I forkant av oppstarten av det nye kurset «Databaser» vi fortsetter å publisere en serie artikler om kryptering i MySQL.

Kryptering i MySQL: bruk av Hovednøkkel

I den forrige artikkelen i denne serien (Kryptering i MySQL: nøglelagring) snakket vi om nøkkellager. I denne artikkelen skal vi se på hvordan hovednøkkelen (master key) brukes, samt diskutere fordeler og ulemper med konvolutkryptering (envelope encryption). 

Ideen bak konvolutkryptering er at nøklene som brukes til å kryptere (nøkler for tabellrom) krypteres med en annen nøkkel (hovednøkkelen, master key). For å kryptere data brukes faktisk nøklene for tabellrom. Grafisk kan dette representeres som:

Kryptering i MySQL: bruk av Hovednøkkel

Hovednøkkelen (master key) er lagret i nøkkellageret (keyring), mens nøklene for tabellrom er i overskriftene til de krypterte tabellrommene (på side 0 av tabellrommet). 

På bildet over:

  • Tabell A er kryptert med nøkkel 1 (Key 1). Nøkkel 1 krypteres med hovednøkkelen (master key) og lagres i kryptert form i overskriften til tabell A.

  • Tabell B er kryptert med nøkkel 2 (Key 2). Nøkkel 2 krypteres med hovednøkkelen (master key) og lagres i kryptert form i overskriften til tabell B.

  • Og så videre.

Når serveren må dekryptere tabell A, henter den hovednøkkelen fra nøkkellageret, leser den krypterte nøkkelen 1 fra overskriften til tabell A og dekrypterer nøkkelen 1. Den dekrypterte nøkkelen 1 blir hurtigbuffer i serverens minne og brukes til å dekryptere tabell A.

InnoDB

I InnoDB utføres den faktiske krypteringen og dekrypteringen på inn- og utgangsnivå. Det vil si at siden krypteres rett før den blir skrevet til disken, og dekrypteres umiddelbart etter lesing fra disken.

I InnoDB fungerer kryptering kun på nivået for tabellrom. Som standard opprettes alle tabeller i separate tabellrom (file-per-table tablespace). Med andre ord, opprettes det et tabellrom som kun kan inneholde én tabell. Selv om du også kan opprette tabeller i det generelle tabellrommet (general tablespace). Men uansett er tabellen alltid i et eller annet tabellrom. Og siden kryptering skjer på tabellromnivå, er det enten fullstendig kryptert eller ikke. Det vil si at du ikke kan kryptere bare deler av tabellene i det generelle tabellrommet. 

Dersom file-per-table er deaktivert av en eller annen grunn, blir alle tabeller opprettet inne i systemtabellområdet (system tablespace). I Percona Server for MySQL kan systemtabellområdet krypteres ved hjelp av innstillingene for innodbsystablespaceencrypt eller ved å bruke krypteringstråder (encryption threads), men dette er fortsatt en eksperimentell funksjon. Dette finnes ikke i MySQL.

Før vi går videre, må vi se på strukturen til hovednøkkel-ID (master key ID). Den består av UUID, KEYID og prefikset «INNODBKey». Det ser slik ut: INNODBKey-UUID-KEYID.

UUID er UUID-en til serveren med det krypterte tabellområdet. KEYID er bare en konstant økende verdi. Ved første opprettelse av hovednøkkelen er KEYID lik 1. Ved rotasjon av nøkkelen, når en ny hovednøkkel opprettes, er KEYID = 2 og så videre. Mer om rotasjon av hovednøkler vil vi diskutere i de påfølgende artiklene i denne serien.

Nå som vi vet hvordan identifikatoren til hovednøkkelen ser ut, la oss se på overskriften for det krypterte tabellområdet. Når tabellområdet krypteres, legges krypteringsinformasjonen til overskriften. Den ser slik ut:

Kryptering i MySQL: bruk av Hovednøkkel

KEY ID er KEYID fra identifikatoren til hovednøkkelen som vi allerede har diskutert. UUID er UUID-en til serveren, som også brukes i identifikatoren til hovednøkkelen. TABLESPACE KEY er nøkkelen til tabellområdet som består av 256 biter tilfeldig generert av serveren. Initialiseringsvektoren (IV, initialization vector) består også av 256 tilfeldig genererte biter (selv om den skal være 128 bit). IV brukes til å initialisere kryptering og dekryptering av AES (av de 256 bitene brukes kun 128). Til slutt er det et CRC32-sjekksum for TABLESPACE KEY og IV.

Hele tiden har jeg forenklet litt ved å si at overskriften har en kryptert nøkkel for tabellområdet. Faktisk lagres nøkkelen til tabellområdet og initialiseringsvektoren sammen, kryptert med hovednøkkelen. Husk at før nøkkelen til tabellområdet og initialiseringsvektoren krypteres, beregnes det en CRC32 for dem.

Hva er poenget med CRC32?

For those unfamiliar, validating the primary key involves decrypting the tablespace key and initialization vector, computing a checksum, and comparing it with the CRC32 stored in the header. If the checksums match, we have the correct primary key and tablespace key. Otherwise, the tablespace is marked as missing (we still won’t be able to decrypt it).

You might ask: when does the key verification take place? The answer is — upon server startup. A server with encrypted tables/tablespaces reads the UUID and KEY from the header at boot.ID from the header and generates the primary key identifier. It then retrieves the required primary key from the keyring, decrypts the tablespace key, and checks the checksum. Again, if the checksum matches, everything is fine; if not, the tablespace is marked as missing.

If you read the previous article in this series (Kryptering i MySQL: nøglelagring), you might remember that when using server key storage, the server at startup only retrieves a list of key identifiers, specifically, key ID and user ID, since this pair uniquely identifies the key. Now I’m saying that the server at startup gets all the keys it needs to verify the possibility of decrypting tablespace keys. So why, during initialization, in the case of server storage, are only the keyid and userid loaded, and not all keys? Because you might not need all keys. This mainly relates to primary key rotation. When the primary key is rotated, a new primary key is created in the storage, but the old keys are not deleted. Thus, in server key storage, you may have many keys that the server does not need and, consequently, are not retrieved on server startup.

Det er på tide å snakke litt om fordelene og ulempene ved kryptering med hovednøkkelen. Den største fordelen er at du kun trenger én krypteringsnøkkel (hovednøkkelen), som vil bli lagret separat fra de krypterte dataene dine. Dette gjør oppstart av serveren rask, og lagringen er liten, noe som letter administrasjonen. I tillegg er hovednøkkelen lett å regenerere.

Men kryptering med hovednøkkelen har en stor ulempe: Når tabellområdet er kryptert med tablespace_key, forblir det alltid kryptert med den samme nøkkelen. Rotasjon av hovednøkkelen hjelper ikke her. Hvorfor er dette en ulempe? Vi vet at det finnes feil i MySQL som kan før til plutselige feil og opprettelse av en kjernefil. Siden kjernefilen inneholder et minnedump av serveren, kan det hende at den avdekker den dekrypterte nøkkelen til tabellområdet. Det som er verre, er at dekrypterte nøkler til tabellområdet lagres i minne som kan byttes ut til disk. Du kan si at dette ikke er en ulempe, da du trenger root-rettigheter for å få tilgang til disse filene og byttepartisjonen. Ja. Men root-rettigheter trengs bare for en kort periode. Når noen har tilgang til den dekrypterte nøkkelen til tabellområdet, kan han/hun fortsette å bruke den for å dekryptere dataene, selv uten root-rettigheter. I tillegg kan disken bli stjålet, og byttepartisjon/kjernefiler kan leses med eksterne verktøy. Målet med TDE er å gjøre det uleselig, selv om disken blir stjålet. Percona Server for MySQL Det er mulig å re-kryptere tabellområdet med nyskapte nøkler. Denne funksjonen kalles krypteringstråder (encryption threads) og var i skrivende stund fortsatt eksperimentell.

Lær mer om kurset

Les mer:

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster