I forklaringen af den nye optagelse til kurset fortsætter vi med at offentliggøre en serie artikler om kryptering i MySQL.

I den forrige artikel i denne serie () talte vi om nøglelagre. I denne artikel vil vi se på, hvordan hovednøglen (master key) bruges, samt diskutere fordele og ulemper ved kuvertkryptering (envelope encryption).
Ideen med kuvertkryptering er, at de nøgler, der bruges til kryptering (tablespace nøgler), krypteres med en anden nøgle (hovednøgle, master key). De faktiske data krypteres med tablespace nøgler. Grafisk kan det fremstå sådan her:

Hovednøglen (master key) findes i nøglelageret (keyring), og tablespace nøglerne findes i overskrifterne af de krypterede tablespaces (på side 0 af tablespace).
På billedet ovenfor:
Tabel A er krypteret med nøgle 1 (Key 1). Nøgle 1 krypteres med hovednøglen (master key) og gemmes i krypteret form i overskriften for tabel A.
Tabel B er krypteret med nøgle 2 (Key 2). Nøgle 2 krypteres med hovednøglen (master key) og gemmes i krypteret form i overskriften for tabel B.
Og så videre.
Når serveren skal dekryptere tabel A, henter den hovednøglen fra nøglelageret, læser den krypterede nøgle 1 fra overskriften for tabel A og dekrypterer nøgle 1. Den dekrypterede nøgle 1 caches i serverens hukommelse og bruges til at dekryptere tabel A.
InnoDB
I InnoDB udføres den faktiske kryptering og dekryptering på input-output niveau. Det vil sige, at siden krypteres lige før den skrives til disk og dekrypteres umiddelbart efter, at den er blevet læst fra disk.
I InnoDB virker kryptering kun på niveauet for tablespaces. Og som standard oprettes alle tabeller i separate tablespaces (). Med andre ord oprettes der et tablespace, der kun kan indeholde én tabel. Men du kan også oprette tabeller i det primære tablespace (). Men uanset hvad er tabellen altid i et eller andet tablespace. Og da krypteringen finder sted på niveauet for tablespace, er den enten helt krypteret eller ikke. Det vil sige, at man ikke kan kryptere kun dele af tabellerne i det primære tablespace.
Hvis file-per-table er deaktiveret af en eller anden grund, oprettes alle tabeller inden for det systemtabellerum (system tablespace). I kan man kryptere systemtabellerummet ved hjælp af variablen innodbsystablespaceencrypt eller ved at bruge krypteringsstrømme (encryption threads), men dette er stadig en eksperimentel funktion. Dette findes ikke i MySQL.
Før vi går videre, er vi nødt til at se på strukturen af hovednøgle-id'et (master key ID). Det består af UUID, KEYID og præfikset "INNODBKey". Det ser sådan ud: INNODBKey-UUID-KEYID.
UUID er serverens uuid med det krypterede tabellerum. KEYID er blot et konstant voksende tal. Ved første oprettelse af hovednøglen er KEYID lig med 1. Ved rotation af nøgle, når en ny hovednøgle oprettes, er KEYID = 2 og så videre. Vi vil tale mere detaljeret om rotation af hovednøgler i de næste artikler i denne serie.
Nu hvor vi ved, hvordan hovednøgle-id'et ser ud, lad os se på overskriften af det krypterede tabellerum. Når tabellerummet krypteres, tilføjes krypteringsinformation til overskriften. Det ser sådan ud:

KEY ID er KEYID fra hovednøgle-id'et, som vi allerede har diskuteret. UUID er serverens uuid, som også bruges i hovednøgle-id'et. TABLESPACE KEY er tabellerummets nøgle, som består af 256 bit, tilfældigt genereret af serveren. Initialiseringsvektoren (IV, initialization vector) består også af 256 tilfældigt genererede bit (selvom det bør være 128 bit). IV bruges til at initialisere AES-kryptering og dekryptering (ud af de 256 bit bruges kun 128). Til slut er der en CRC32-kontrolsum for TABLESPACE KEY og IV.
Hele tiden har jeg forenklet lidt ved at sige, at der er en krypteret tabelrumss nøgle i overskriften. Faktisk opbevares og krypteres tabellerummets nøgle og initialiseringsvektoren sammen ved hjælp af hovednøglen. Husk, at før krypteringen af tabellerummets nøgle og initialiseringsvektoren beregnes CRC32 for dem.
Hvad er formålet med CRC32?
Kort sagt, for at sikre gyldigheden af den primære nøgle. Efter dekryptering af tabeller og initialiseringsvektoren beregnes en kontrolsum, som sammenlignes med den gemte CRC32 i headeren. Hvis checksummene stemmer overens, har vi den korrekte primære nøgle og tabelnøglen. Ellers markeres tabellen som manglende (vi kan stadig ikke dekryptere den).
Du kan spørge: Hvornår sker kontrol af nøgler? Svaret er — ved serverstart. Serveren med krypterede tabeller / tabeller læser UUID, KEYID fra headeren og genererer en primær nøgleidentifikator. Derefter hentes den nødvendige primære nøgle fra nøglelageret (keyring), dekrypterer tabelnøglen og kontrollerer kontrolsummen. Igen, hvis kontrolsummen stemmer overens, så er alt i orden, hvis ikke — markeres tabellen som manglende.
Hvis du har læst den tidligere artikel i denne serie (), husker du måske, at når der anvendes et servernøglelager, modtager serveren ved opstart kun en liste over nøgleidentifikatorer, mere præcist key id og user id, da dette par entydigt identificerer nøglen. Og nu siger jeg, at serveren ved opstart får alle de nøgler, den behøver for at kontrollere muligheden for at dekryptere tabelnøgler. Så hvorfor indlæses der kun keyid og userid ved initialisering, og ikke alle nøgler? Fordi du måske ikke har brug for alle nøglerne. Dette hænger primært sammen med rotationen af den primære nøgle. Ved rotation af den primære nøgle oprettes en ny primær nøgle i lageret, men de gamle nøgler slettes ikke. Således kan der i servernøglelageret være mange nøgler, som serveren ikke behøver, og som derfor ikke hentes ved serverstart.
Det er tid til at tale lidt om fordele og ulemper ved kryptering ved hjælp af en master-nøgle. Den største fordel er, at du kun har brug for én krypteringsnøgle (master-nøgle), som bliver opbevaret separat fra dine krypterede data. Dette gør serveropsætningen hurtig, og lagerpladsen er lille, hvilket letter administrationen. Og desuden er det nemt at regenerere den eneste master-nøgle.
Men kryptering med master-nøglen har en stor ulempe: Når tabelrummet er krypteret med tablespace_key, forbliver det altid krypteret med den samme nøgle. Rotation af master-nøglen hjælper ikke her. Hvorfor er det en ulempe? Vi ved, at der er bugs i MySQL, som kan føre til pludselige nedbrud og skabe core-filer. Da core-filen indeholder en dump af serverens hukommelse, kan det ske, at den dump indeholder den dekrypterede tabelrum-nøgle. Endnu værre, dekrypterede tabelrum-nøgler opbevares i hukommelsen, som kan swap'es til disken. Du kan sige, at dette ikke er en ulempe, da du har brug for root-rettigheder for at få adgang til disse filer og swap-partitionen. Ja. Men root-adgang kræves kun i en kort periode. Så snart nogen får adgang til den dekrypterede tabelrum-nøgle, kan han/hun fortsætte med at bruge den til at dekryptere data, selv uden root-rettigheder. Desuden kan disken blive stjålet, og swap-partitionen/core-filerne kan læses med tredjeparts værktøjer. Formålet med TDE er at gøre det ulæseligt, selv hvis disken bliver stjålet. der er mulighed for at re-kryptere tabelrummet med nye genererede nøgler. Denne funktion kaldes krypteringstråde (encryption threads) og er på tidspunktet for skrivningen af denne artikel stadig eksperimentel.
Læs mere:
Kilde: habr.com
