Hoppa yfir í efnið

Samhverf dulritun

Í síðasta kafla notuðum við XOR og skoðuðum einnota lykla. Nú færum við okkur nær dulritunarkerfum sem eru notuð í raunheimum.

Samhverf dulritun (e. symmetric encryption) notar sama leyndarmálið til að dulrita og dulráða gögn. Hugmyndin er því svipuð og í læstum kassa: Anna og Bjarni þurfa báðir að hafa réttan lykil.

Anna                              Bjarni
  │                                   │
  │ sameiginlegur leynilykill        │
  └──────────────┬────────────────────┘
                 │
     dulrita ─► gögn ◄─ dulráða

Samhverf dulritun er yfirleitt mjög hröð og hentar því vel fyrir stórar skrár, myndbönd og löng skilaboð. Vandamálið er að Anna og Bjarni þurfa að koma sameiginlega lyklinum örugglega til hvors annars.

XOR var byggingareining

XOR-dæmin í síðasta kafla voru gagnleg til að skilja grundvallarhugmyndina: gögn eru sameinuð lykli og hægt er að nota lykilinn aftur til að endurheimta gögnin. Nútímaleg samhverf dulritun notar miklu flóknari og vandlega prófuð algrím en einfalt XOR.

Hvað þarf gott kerfi að geta?

Gott samhverft dulmálskerfi þarf meira en eitt dulritunaralgrím. Við þurfum að hugsa um:

  • dulritunaralgrímið: reglurnar sem breyta gögnunum,
  • lykilinn: leyndarmálið sem stjórnar útreikningunum,
  • frumstillivigur eða nonce: viðbótargildi sem hjálpar til við að tryggja að sama skilaboð gefi ekki sömu útkomu í hvert skipti,
  • auðkenningarmerki: upplýsingar sem gera okkur kleift að sjá hvort einhver hafi breytt dultextanum.

Lykillinn á að vera leyndur. Frumstillivigur og nonce mega oft vera send með dultextanum, en þau þurfa að uppfylla sérstakar reglur. Við lærum um það hér á eftir.

Bálkadulritun og straumdulritun

Það eru margar leiðir til að vinna með gögn. Tvær mikilvægar hugmyndir eru bálkadulritun (e. block cipher) og straumdulritun (e. stream cipher).

Bálkadulritun

Bálkadulritun vinnur með jafnstóra bita- eða bætabálka í einu. Ef algrímið notar 16 bæta bálka þarf það að vita hvað á að gera ef gögnin eru ekki nákvæmlega margfeldi af 16 bæti.

Skilaboð:  [bálki 1] [bálki 2] [síðasti hluti]
                           └─ þarf hugsanlega fyllingu

Fylling (e. padding) eru viðbótarbæti sem eru sett aftan við gögnin svo síðasti bálkurinn verði nógu langur. Fyllingin verður að vera þannig að viðtakandinn geti fjarlægt hana aftur án þess að ruglast á fyllingu og raunverulegum gögnum.

Straumdulritun

Straumdulritun býr til bita- eða bætarunu sem er sameinuð gögnunum smám saman, oft með XOR:

Gögn       ⊕  Dulritunarstraumur  =  Dultexti
Dultexti   ⊕  Sami straumur       =  Gögn

Þetta líkist XOR-dulrituninni sem við skoðuðum, en traust straumdulritun notar vandlega hannað algrím til að búa til strauminn. Stóri lærdómurinn úr síðasta kafla stendur samt: ekki má endurnota sama dulritunarstraum með sama lykli.

AES: algengt bálkadulmál

AES (e. Advanced Encryption Standard) er eitt þekktasta staðlaða samhverfa dulritunaralgrímið. Það vinnur með 16 bæta bálka og styður 128, 192 og 256 bita lykla.

Við ætlum ekki að útfæra AES sjálf. Innri skrefin eru mörg og auðvelt væri að gera villu sem eyðileggur öryggið. Það sem skiptir máli á þessu stigi er:

  • AES er algrím, ekki lykill.
  • AES-256 þýðir AES með 256 bita lykli, ekki að skilaboðin séu alltaf 256 bitar.
  • Sama lykillinn má ekki einfaldlega gefa sömu útkomu fyrir sama texta í hvert skipti.
  • AES eitt og sér segir ekki hvernig bálkarnir eru tengdir saman eða hvernig breytingar eru uppgötvaðar.

Vissir þú?

AES varð til eftir alþjóðlega samkeppni þar sem mörg dulritunaralgrím voru opinberlega rannsökuð. Vinningsalgrímið hét upphaflega Rijndael og var hannað af Joan Daemen og Vincent Rijmen. Alþjóðleg skoðun var hluti af því að treysta staðlinum.

ECB: þegar mynstur leka

Auðveldasta leiðin til að nota bálkadulritun væri að dulrita hvern bálk alveg sjálfstætt. Sá hamur kallast ECB (e. Electronic Codebook).

Sami frumtextabálkur + sami lykill = sami dultextabálkur

Þetta lekur mynstrum. Ef sama bálkur kemur fyrir tíu sinnum birtist sami dultextabálkur tíu sinnum. Þótt við sjáum ekki innihaldið getum við séð að hlutarnir eru eins.

Sýnidæmi: bálkar sem endurtaka sig

Segjum að við höfum fjóra frumtextabálka:

A B A C

Ef A og B eru sömu gögn í bæði skiptin og ECB er notað fáum við eitthvað á þessa leið:

X Y X Z

Við vitum þá að fyrsti og þriðji bálkurinn voru eins, jafnvel þótt við vitum ekki hvað X stendur fyrir.

Vissir þú?

Frægasta kennsludæmið um ECB er mynd af mörgæsinni Tux. Þegar myndin er dulrituð með ECB sjást útlínur myndarinnar enn, því sömu myndahlutar gefa sömu dultextabálka. Dulritunin felur litina en ekki mynstrið.

Æfing: finndu lekið mynstur

Æfing 1

Frumtextinn skiptist í bálka:

A B A A C B

ECB skilar eftirfarandi dultextabálkum:

X Y X X Z Y
  1. Hvaða frumtextabálkar voru eins?
  2. Hvað getum við sagt um A og X?
  3. Hvers vegna er þetta upplýsingaleki þótt við vitum ekki innihald A?
Lausn við æfingu 1
  1. A kemur fyrir í fyrsta, þriðja og fjórða sæti. Dultextinn X kemur fyrir á nákvæmlega sömu stöðum. B kemur fyrir í öðru og sjötta sæti og gefur Y í bæði skiptin.
  2. Við vitum að A var breytt í X með þessum lykli og ECB-stillingu.
  3. Við vitum að sama gögn komu fyrir á þremur stöðum. Það getur gefið upplýsingar um uppbyggingu, endurtekningar eða hvaða hlutar skjalsins eru eins. Örugg dulritun á ekki að leka slíkum mynstrum að óþörfu.

Forðastu ECB

ECB er yfirleitt ekki rétt val fyrir alvöru skilaboð eða skrár. Það er hér vegna þess að það sýnir mjög skýrt hvað getur farið úrskeiðis þegar bálkar eru meðhöndlaðir sjálfstætt.

CBC og frumstillivigur

Í CBC (e. Cipher Block Chaining) er hver frumtextabálkur tengdur við fyrri dultextabálk áður en hann er dulritaður. Fyrsti bálkurinn hefur engan fyrri dultextabálk, svo þar er notað sérstakt upphafsgildi sem kallast frumstillivigur (e. initialization vector, IV).

Mjög einfaldað lítur ferlið svona út:

Fyrsti bálkur:   P₁ ⊕ IV       ─► dulritun ─► C₁
Annar bálkur:    P₂ ⊕ C₁       ─► dulritun ─► C₂
Þriðji bálkur:   P₃ ⊕ C₂       ─► dulritun ─► C₃

Frumstillivigurinn þarf yfirleitt ekki að vera leyndur. Hann þarf hins vegar að vera valinn rétt og oft þarf hann að vera ófyrirsjáanlegur. Við getum sent hann með dultextanum:

IV || C₁ || C₂ || C₃

Hér táknar || að gögnin séu sett saman í eina röð.

Ef sami lykill og sami IV eru notuð aftur fyrir sama upphaf frumtextans getur sami fyrsti dultextabálkur komið út aftur. Því má ekki velja fast IV eins og allt-núll-bætarunu fyrir hvert skilaboð.

Æfing: hvað er leyndarmál?

Æfing 2

Þú finnur eftirfarandi í skilaboði:

IV || dultexti
  1. Þarf IV að vera leyndur eins og lykillinn?
  2. Er í lagi að nota sama IV aftur með sama lykli?
  3. Hvað gæti gerst ef IV er fastur og skilaboð byrja oft á sama texta?
Lausn við æfingu 2
  1. IV þarf yfirleitt ekki að vera leyndur. Viðtakandinn þarf að hafa hann til að dulráða og hann má því fylgja dultextanum.
  2. Það er almennt ekki í lagi að endurnota sama IV með sama lykli. Endurnotkun getur lekið mynstrum, sérstaklega í upphafi skilaboða.
  3. Ef skilaboð byrja á sama frumtextabálki getur sami fyrsti dultextabálkur komið út. Hlerari getur þá séð að upphafin séu eins, jafnvel þótt hann sjái ekki textann sjálfan.

CTR: bálkar sem verða að straumi

Í CTR (e. Counter mode) er teljari notaður með nonce og lykli til að búa til dulritunarstraum. Straumurinn er síðan XOR-aður við gögnin.

Lykill + nonce + teljari  ─►  dulritunarstraumur
Gögn ⊕ dulritunarstraumur  ─►  dultexti

CTR þarf enga fyllingu fyrir síðasta hlutann, því hægt er að nota aðeins þann hluta straumsins sem þarf. Það er líka hægt að vinna úr mismunandi hlutum gagna samhliða.

En hér er mikilvæg regla:

Nonce má ekki endurtaka

Ef sami lykill og sami nonce eru notuð tvisvar í CTR myndast sami dulritunarstraumur. Þá er staðan svipuð og þegar XOR-lykill er endurnotaður: með því að XOR-a dultextana saman getur lykillinn eða straumurinn horfið úr jöfnunni.

Sýnidæmi: sami straumur tvisvar

Látum:

C₁ = P₁ ⊕ S
C₂ = P₂ ⊕ S

Hér er S dulritunarstraumurinn sem fæst úr lykli og nonce. Þá gildir:

C₁ ⊕ C₂ = P₁ ⊕ P₂

Þetta er nákvæmlega sama vandamál og við sáum í kaflanum um einnota lykla. Nýtt nonce í hvert skipti kemur ekki í stað leynds lykils, en það kemur í veg fyrir að sami straumurinn sé búinn til aftur með sama lyklinum.

Auðkennd dulritun

Dulritun verndar leynd, en við þurfum líka að sjá hvort einhver hafi breytt dultextanum. Ein leið er að nota auðkennda dulritun (e. authenticated encryption), sem gefur bæði dultexta og auðkenningarmerki (e. authentication tag).

Dulrita(lykill, nonce, skilaboð)
        └──────────────► dultexti + merki

Viðtakandinn notar merkið þegar hann dulráðar:

Dulráða(lykill, nonce, dultexti, merki)
        ├─ rétt merki  → frumtexti
        └─ rangt merki → villa

Merkið sýnir að gögnin hafi ekki breyst og að einhver sem þekkir ekki lykilinn hafi ekki búið til gilt nýtt dultextagildi. Það tryggir ekki endilega hver manneskjan er — til þess þarf stærra auðkenningarkerfi — en það verndar heilleika gagna.

Algengar aðferðir eru:

  • AES-GCM, sem sameinar AES við auðkenningu,
  • ChaCha20-Poly1305, sem er straumkennd aðferð með auðkenningu.

Þegar við getum valið er yfirleitt betra að nota svokallaða AEAD-aðferð (e. Authenticated Encryption with Associated Data) í stað þess að reyna að sameina dulritun og kjötkássu sjálf.

Hvað eru „associated data“?

Stundum viljum við auðkenna upplýsingar án þess að dulrita þær. Til dæmis má vilja að útgáfunúmer eða viðtakandi sé sýnilegur en ekki breytanlegur.

Sýnileg lýsigögn ──► auðkennd en ekki dulrituð
Leynd skilaboð    ──► dulrituð og auðkennd

Þessi sýnilegu gögn kallast associated data. Ef einhver breytir þeim á samt auðkenningarmerkið ekki lengur við og dulráðningin á að mistakast.

Æfing: veldu rétt kerfi

Æfing 3

Veldu besta lýsinguna fyrir hvert verkefni:

  1. Mynd af gagnagrunni þarf að vera leynd en einnig þarf að vita hvort hún hafi breyst.
  2. Forrit vill senda leynd skilaboð og nonce með skilaboðunum.
  3. Forrit notar AES-ECB vegna þess að „AES er öruggt“.
  4. Forrit notar AES-GCM en notar sama nonce aftur með sama lykli.

Veldu úr: AEAD, straumdulritun með einstökum nonce, ECB er slæmt val, eða nonce-endurnotkun er villa.

Lausn við æfingu 3
  1. AEAD. Við viljum bæði leynd og heilleika. AEAD skilar dultexta og auðkenningarmerki.
  2. Straumdulritun með einstökum nonce. Nonce má vera sýnilegur, en hann þarf að vera nýr fyrir hvern notkunartilfelli með sama lykli.
  3. ECB er slæmt val. AES getur verið traust algrím en ECB-stillingin getur lekið mynstrum.
  4. Nonce-endurnotkun er villa. Sérstaklega í GCM og CTR getur endurnotkun með sama lykli lekið upplýsingum og jafnvel eyðilagt auðkenninguaröryggið.

Örugg notkun úr Python

Við ættum ekki að skrifa AES, GCM eða ChaCha20 sjálf. Við notum þekkt bókasöfn sem hafa verið rannsökuð og prófuð.

Eftirfarandi dæmi sýnir hugmyndina með cryptography-safninu:

import secrets
from cryptography.hazmat.primitives.ciphers.aead import AESGCM

lykill = AESGCM.generate_key(bit_length=256)
aes = AESGCM(lykill)

nonce = secrets.token_bytes(12)
skilabod = b"Leynd skilaboed"
upplysingar = b"utgafa=1"  # auðkennd en ekki dulrituð

dultexti = aes.encrypt(nonce, skilabod, upplysingar)

# Viðtakandinn þarf sama lykil, nonce, dultexta og upplysingar.
frumtexti = aes.decrypt(nonce, dultexti, upplysingar)
assert frumtexti == skilabod

Í þessu dæmi:

  • lykill er leyndur,
  • nonce má fylgja dultextanum en má ekki endurtaka með sama lyklinum,
  • upplysingar eru auðkenndar en ekki dulritaðar,
  • dultexti inniheldur bæði dulrituðu gögnin og auðkenningarmerkið,
  • decrypt á að gefa villu ef einhver breytir dultextanum eða upplysingar.

Kóði er ekki sjálfkrafa tilbúinn í framleiðslu

Dæmið sýnir rétta hugmynd en raunveruleg kerfi þurfa einnig örugga lyklageymslu, skýrt gagnasnið, villumeðhöndlun og prófanir. Ekki vista lykilinn í frumkóðanum og ekki búa til nonce með föstu gildi.

Æfing: finndu villurnar

Æfing 4

Hvað er athugavert við þetta sýnidæmi?

lykill = b"lykilur"
nonce = b"000000000000"

dultexti1 = encrypt(lykill, nonce, b"fyrsta skilabod")
dultexti2 = encrypt(lykill, nonce, b"annad skilabod")

Nefndu að minnsta kosti þrjú vandamál.

Lausn við æfingu 4
  1. Lykillinn er fastur og líklega veikur. Textinn b"lykilur" er stuttur, fyrirsjáanlegur og ekki búinn til með öruggri slembni.
  2. Nonce er fastur. Sama nonce er notaður aftur með sama lyklinum.
  3. Nonce er ekki slembinn eða einstakur. b"000000000000" gefur enga tryggingu fyrir réttri notkun.
  4. Ekki sést hvort encrypt býr til auðkenningarmerki. Ef ekki getur árásarmaður hugsanlega breytt dultextanum án þess að það uppgötvist.
  5. Það sést ekki hvernig lykillinn er geymdur eða sendur. Lyklastjórnun er hluti af örygginu, ekki smáatriði sem má sleppa.

Algeng mistök

Þegar við sjáum samhverfa dulritun í kóða skulum við leita að þessum merkjum:

  • eigin dulritunaralgrím í stað staðlaðs bókasafns,
  • AES-ECB eða sambærileg stilling sem lekur mynstrum,
  • fastur eða endurnotaður IV eða nonce,
  • engin auðkenningu eða auðkenningarmerki,
  • lykill búinn til úr venjulegu aðgangsorði án lykilafleiðslu,
  • lyklar skrifaðir beint í frumkóða eða stillingaskrár sem allir geta lesið,
  • sama lykill notaður í ólíkum tilgangi án skýrrar áætlunar.

Samantekt

Í þessum kafla lærðum við að:

  • samhverf dulritun notar sameiginlegan leynilykil,
  • bálkadulritun vinnur með föstum bálkum en straumdulritun með straumi gagna,
  • AES er staðlað algrím en þarf rétta stillingu og notkun,
  • ECB lekur endurteknum mynstrum,
  • frumstillivigur og nonce þurfa að vera notuð samkvæmt reglum og oft ný í hvert skipti,
  • endurnotkun nonce getur verið jafn alvarleg og endurnotkun XOR-lykils,
  • auðkennd dulritun veitir bæði leynd og vörn gegn breytingum,
  • AEAD-aðferðir eins og AES-GCM og ChaCha20-Poly1305 eru betri upphafspunktur en eigin samsetningar,
  • við eigum að nota þekkt bókasöfn og geyma lykla á öruggan hátt.

Næst skoðum við kjötkássur og lykilorð. Þar skiptir máli að skilja muninn á því að geta dulráðið gögn og því að geta aðeins sannreynt þau.