Tætiföll, lykilorð og skeytisauðkenning
Í köflunum hingað til höfum við oft viljað breyta gögnum þannig að hægt sé að breyta þeim aftur. Nú skoðum við aðra hugmynd: að búa til stutt fingrafar gagna sem við getum notað til að bera saman eða sannreyna gögn.
Þetta fingrafar kemur frá tætifalli (e. hash function). Tætifall er ekki dulritun og útkoman er ekki eitthvað sem við eigum að dulráða.
Stóra aðgreiningin
Dulritun er yfirleitt afturkræf með réttum lykli. Tætifall á að vera einátta: auðvelt að reikna tætigildið út frá gögnum, en erfitt að finna upprunalegu gögnin út frá tætigildinu.
Hvað gerir tætifall?
Tætifall tekur gögn af hvaða stærð sem er og skilar tætigildi af fyrirfram ákveðinni gerð eða lengd.
Gögn af hvaða stærð sem er ──► Tætifall ──► Fastmótað tætigildi
Til dæmis skilar SHA-256 alltaf 256 bitum, sem eru oft skrifaðir sem 64 sextándakerfisstafir.
Sýnidæmi: SHA-256
Í Python getum við reiknað SHA-256 með hashlib:
import hashlib
gogn = b"hello"
ni = hashlib.sha256(gogn).hexdigest()
print(ni)
Útkoman er:
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Ef við breytum aðeins einum staf:
hashlib.sha256(b"Hello").hexdigest()
verður útkoman allt önnur. Við getum því ekki skoðað tætigildin og gert ráð fyrir að lítil breyting á inntaki gefi litla breytingu á úttaki.
Helstu eiginleikar
Gott dulritunar-tætifall ætti að hafa nokkra eiginleika:
- Ákveðin útkoma: Sama inntak gefur alltaf sama tætigildi.
- Hröð útreikningur: Það á að vera auðvelt að reikna gildið fyrir gögnin.
- Mikil dreifing: Lítil breyting á inntaki á að breyta úttakinu verulega.
- Erfitt að snúa við: Út frá tætigildinu á að vera erfitt að finna inntakið.
- Erfitt að finna árekstur: Það á að vera erfitt að finna tvö ólík inntök með sama tætigildi.
Tætifall þarf ekki að vera leyndarmál. SHA-256 er opinbert algrím og allir mega nota það. Öryggið felst í eiginleikum þess, ekki í því að fela hvernig það virkar.
Æfing: hvað breytist?
Æfing 1
Hvaða fullyrðingar eru réttar?
- Sama texti gefur alltaf sama SHA-256-tætigildi.
- Ef tveir textar hafa sama SHA-256-tætigildi eru þeir örugglega nákvæmlega eins.
- SHA-256 er hægt að „afkóða“ með leynilykli.
- Einn breyttur stafur getur breytt öllu tætigildinu.
Lausn við æfingu 1
- Rétt. Dulritunar-tætifall er ákveðið: sama inntak gefur sama úttak.
- Ekki alveg. Ef tveir ólíkir textar hafa sama tætigildi er það kallað árekstur. Gott tætifall gerir slíka árekstra mjög ólíklega, en stærðfræðilega er ekki hægt að hafa einkvæmt tætigildi fyrir öll möguleg gögn þegar úttakið hefur fasta lengd.
- Rangt. Tætifall er ekki dulkóðun og hefur engan afkóðunarlykil.
- Rétt. Þetta er mikilvægur eiginleiki: lítil breyting á inntaki á að valda mikilli breytingu á úttakinu.
Tætifall er ekki dulritun
Við skulum bera saman þrjár aðferðir:
| Aðferð | Hægt að endurheimta frumgögn? | Þarf leyndarmál? | Dæmigerð notkun |
|---|---|---|---|
| Base64-kóðun | Já, með opinberum reglum | Nei | Framsetning gagna |
| Dulritun | Já, með lykli | Já | Leynd gagna |
| Tætifall | Ekki á að vera hægt | Ekki endilega | Samanburður og sannprófun |
Sýnidæmi: að geyma skrá
Þegar við sækjum stóra skrá getum við fengið SHA-256-tætigildi með henni:
Skrá frá útgefanda: report.zip
Uppgefið tætigildi: abc123...
Við reiknum sjálf tætigildi af skránni sem við sóttum og berum saman:
Reiknað hjá okkur: abc123...
Uppgefið frá útgefanda: abc123...
Ef gildin eru ólík getur skráin hafa skemmst eða einhver breytt henni.
En hér er mikilvægt smáatriði: ef árásarmaður getur skipt út bæði skránni og uppgefna tætigildinu, þá hjálpar einfaldur samanburður ekki. Til að sannreyna hver gaf út gildið þarf til dæmis stafræna undirskrift. Við skoðum slíkt síðar.
Vissir þú?
Git notar tætigildi víða til að auðkenna útgáfur og hluti í gagnagrunni sínum. Þegar þú skoðar commit-sögu eru löngu strengirnir ekki leyndarmál; þeir eru auðkenni sem byggja á innihaldi.
Árekstrar og stærð úttaksins
Árekstur (e. collision) verður þegar tvö ólík inntök gefa sama tætigildi:
Tætifall("A") = X
Tætifall("B") = X
Við viljum að erfitt sé að finna slíkt par. Ekki er hægt að útiloka árekstra algjörlega ef úttakið hefur fasta lengd. Það eru óendanlega mörg möguleg inntök en aðeins endanlega mörg möguleg tætigildi.
Þetta þýðir samt ekki að hægt sé að finna árekstur auðveldlega. Gott tætifall er hannað þannig að leitin sé mjög erfið.
Af hverju eru SHA-1 og MD5 ekki góð fyrir ný verkefni?
MD5 og SHA-1 voru lengi notuð í ýmsum kerfum, en þekktir veikleikar gera þau óhentug þegar við þurfum sterka vörn gegn árekstrum. Fyrir ný kerfi ættum við að velja nútímalegri aðferðir, eins og SHA-256 eða SHA-3, eftir því hvaða verkefni við erum að leysa.
Vissir þú?
Árið 2017 sýndu rannsakendur svokallað SHAttered-verkefni: þeir smíðuðu tvær ólíkar PDF-skrár með sama SHA-1-tætigildi. Þetta var mikilvæg áminning um að „notað í mörg ár“ er ekki það sama og „öruggt að eilífu“.
Lykilorð og gagnagrunnar
Vefþjónn þarf oft að geta sannreynt að aðgangsorð sem notandi slær inn sé rétt. En hvernig ætti hann að geyma aðgangsorðið?
Slæm leið: geyma það óbreytt
notandi: anna
aðgangsorð: sumar2026
Ef gagnagrunnurinn lekur geta allir lesið aðgangsorðin. Þetta er mjög slæmt, sérstaklega vegna þess að fólk endurnotar oft sama aðgangsorðið á mörgum vefjum.
Önnur slæm leið: dulkóða aðgangsorðið
Ef vefurinn getur dulráðið öll aðgangsorðin þarf hann að geyma lykil sem getur gert það. Ef gagnagrunnur og lykill leka saman eru aðgangsorðin aftur komin í ljós.
Betri hugmynd: geyma tætigildi
Við getum geymt tætigildi í stað aðgangsorðsins:
Aðgangsorð ──► Tætifall ──► Geymt tætigildi
Þegar notandinn skráir sig inn:
- Vefurinn tekur við innslátta aðgangsorðinu.
- Hann beitir sömu aðferð til að reikna tætigildi.
- Hann ber nýja gildið saman við geymda gildið.
- Ef þau eru eins passar aðgangsorðið.
Vefurinn þarf þá ekki að geyma aðgangsorðið sjálft.
SHA-256 eitt og sér er ekki nóg fyrir aðgangsorð
SHA-256 er hannað til að vera mjög hratt. Það er gott þegar við viljum reikna tætigildi skráa hratt, en slæmt fyrir aðgangsorð: árásarmaður getur prófað milljónir giska á stuttum tíma.
Salt og hæg lykilorðaaðferð
Til að gera lykilorðageymslu betri notum við salt (e. salt). Salt er slembin bætaruna sem er lögð við eða notuð með aðgangsorðinu áður en tætigildið er reiknað.
salt + aðgangsorð ──► hæg lykilorðaaðferð ──► geymt gildi
Salt þarf ekki að vera leynt. Það má geyma við hlið tætigildisins.
Af hverju hjálpar salt?
Segjum að tvær manneskjur noti sama aðgangsorðið:
anna → sama aðgangsorð
björn → sama aðgangsorð
Án salts myndu þær fá sama geymda tætigildið. Með ólíku, slembnu salti fá þær ólík gildi:
salt A + sumar2026 ─► gildi A
salt B + sumar2026 ─► gildi B
Salt kemur ekki í veg fyrir að árásarmaður giski á algeng aðgangsorð. Það kemur hins vegar í veg fyrir að sama tilbúna giskaskráin nýtist beint fyrir alla notendur og gerir forútreiknuð gagnasöfn mun síður gagnleg.
Aðferðin þarf líka að vera hæg og stillanleg. Algengar aðferðir fyrir aðgangsorð eru Argon2id, scrypt, bcrypt og PBKDF2. Þær láta hvert gisk taka vísvitandi tíma og nota oft einnig minni.
Vissir þú?
Salt þarf ekki að vera eins og leynilegt piparbragð. Nafnið hljómar eins og það eigi að fela saltið, en öryggið felst í því að salt sé einstakt og slembið — ekki í því að gagnagrunnurinn geti ekki lesið það.
Sýnidæmi: hvað er í gagnagrunninum?
Öruggari færsluskrá gæti litið svona út:
notandi: anna
salt: 8f2c... # má vera sýnilegt
aðferð: Argon2id
gildi: 91ab... # kemur frá aðferðinni
Þegar Anna skráir sig inn er nýja innslátta aðgangsorðið notað með sama salti og sömu stillingum. Niðurstaðan er síðan borin saman við gildi.
Við geymum ekki:
aðgangsorð: sumar2026
og við geymum ekki einfalt SHA-256-gildi án salts og hægrar lykilorðaaðferðar.
Æfing: finndu slæmu geymsluna
Æfing 2
Hver af þessum gagnagrunnsfærslum er skárri og hvers vegna?
A:
notandi: anna
aðgangsorð: sumar2026
B:
notandi: anna
sha256: 3b7c...
C:
notandi: anna
salt: 91af...
aðferð: Argon2id
gildi: 7aa2...
Lausn við æfingu 2
C er skársti kosturinn. Þar er notuð sérhæfð lykilorðaaðferð, salt er geymt með niðurstöðunni og raunverulegt aðgangsorð er ekki í færslunni.
A er verst. Allir sem lesa gagnagrunninn fá aðgangsorðið beint.
B er betra en A en samt ekki nógu gott. SHA-256 er hratt og salt vantar. Árásarmaður getur prófað algeng aðgangsorð mjög hratt og borið niðurstöðurnar saman við 3b7c....
Salt eitt og sér gerir ekki hraða SHA-256-aðferð að góðri lykilorðaaðferð. Við þurfum bæði einstakt salt og hæga, sérhæfða aðferð.
HMAC: leyndur lykill með tætifalli
Tætifall eitt og sér auðkennir ekki hver sendi skilaboð. Ef allir þekkja SHA-256 geta allir breytt skilaboðum og reiknað nýtt SHA-256-gildi.
Til að auðkenna skeyti milli aðila sem deila leyndum lykli getum við notað HMAC (e. Hash-based Message Authentication Code). HMAC sameinar leyndan lykil og traust tætifall á vandlega skilgreindan hátt.
Skeyti + leyndur lykill ──► HMAC ──► [auðkenningarkóði](../glossary.md#auðkenningarkodi)
Sendandinn sendir skeytið og HMAC-gildið. Viðtakandinn reiknar HMAC aftur með sama lyklinum. Ef gildin passa hefur skeytið líklega ekki breyst.
Sýnidæmi: HMAC í Python
import hashlib
import hmac
lykill = b"sameiginlegt leyndarmal"
skeyti = b"Flytjum fundinn til klukkan fjogur"
merki = hmac.new(lykill, skeyti, hashlib.sha256).hexdigest()
print(merki)
Viðtakandinn reiknar merkið aftur. Við samanburð ættum við að nota hmac.compare_digest í stað venjulegs ==:
mottak_merki = hmac.new(lykill, skeyti, hashlib.sha256).hexdigest()
if hmac.compare_digest(merki, mottak_merki):
print("Skeytið er óbreytt miðað við lykilinn")
else:
print("Skeytið passar ekki")
compare_digest er hannað til að draga úr upplýsingaleka úr tímasetningu samanburðarins. Við förum nánar yfir slíka tímasetningarárás síðar; í bili er lærdómurinn einfaldur: notum rétta samanburðaraðferð fyrir leynd gildi.
HMAC er ekki dulkóðun
HMAC felur ekki skeytið. Allir sem sjá netumferðina geta lesið skeyti, en þeir geta ekki búið til gilt nýtt HMAC án leynda lykilsins.
Æfing: hash eða HMAC?
Æfing 3
Anna og Bjarni deila leyndum lykli. Þau vilja senda skeyti þannig að Bjarni geti séð hvort Marta hafi breytt því.
- Er nóg að senda
skeyti || SHA256(skeyti)? - Hvað ættu þau að nota?
- Hvað verndast og hvað verndast ekki?
Lausn við æfingu 3
- Nei. Marta getur breytt skeytinu og reiknað nýtt SHA-256-gildi, því SHA-256 þarf engan leyndan lykil.
- Anna og Bjarni ættu að nota HMAC með sameiginlega leynda lyklinum.
- HMAC hjálpar Bjarna að sjá hvort skeytið hafi breyst og hvort sá sem bjó merkið til hafi haft lykilinn. HMAC felur hins vegar ekki skeytið og sannar ekki sjálfkrafa að tiltekinn einstaklingur hafi búið merkið til, því bæði Anna og Bjarni þekkja sama lykilinn.
Hvað leysir hvaða verkfæri?
Það er auðvelt að nota rangt verkfæri ef við hugsum aðeins um „öryggi“ í heild sinni:
| Vandamál | Hentugt verkfæri |
|---|---|
| Fela stór skilaboð | Samhverf dulritun með AEAD |
| Sannreyna að skrá hafi ekki breyst | Dulritunar-tætifall eða undirskrift, eftir því hver ógnin er |
| Geyma aðgangsorð | Hæg lykilorðaaðferð með einstöku salti |
| Auðkenna skeyti milli aðila með sameiginlegan lykil | HMAC |
| Búa til sýnilegt auðkenni gagna | Tætigildi |
Lokaverkefni: greindu kerfið
Æfing 4
Vefþjónn gerir eftirfarandi:
- Geymir
SHA256(password)án salts. - Sækir skrá og ber SHA-256 hennar saman við gildi sem kom frá sama óstaðfesta niðurhalssvæðinu.
- Sendir leynd skilaboð ásamt HMAC, en sendir þau ódulrituð.
- Notar Argon2id með nýju salti fyrir hvert aðgangsorð.
Hvað er rétt, hvað er ófullnægjandi og hvað er gott?
Lausn við æfingu 4
- Ófullnægjandi. SHA-256 er of hratt fyrir lykilorð og salt vantar.
- Ófullnægjandi gegn virkum árásarmanni. Þetta getur fundið skemmdar niðurhalsskrár, en ef árásarmaður getur breytt bæði skránni og uppgefna tætigildinu er samanburðurinn ekki sönnun á uppruna.
- Ófullnægjandi. HMAC verndar heilleika og uppruna miðað við sameiginlega lykilinn, en felur ekki innihaldið. Nota þarf dulkóðun líka, helst AEAD.
- Gott upphaf. Argon2id er hönnuð fyrir aðgangsorð og nýtt salt fyrir hvert gildi kemur í veg fyrir að sams konar aðgangsorð gefi sjálfkrafa sama geymda gildi.
Samantekt
Í þessum kafla lærðum við að:
- tætifall breytir gögnum í fastmótað tætigildi,
- tætifall er ekki dulritun og hefur engan afkóðunarlykil,
- góð tætiföll eiga að gefa mikla breytingu eftir lítið inntaksbreytingu og gera árekstra erfiða,
- SHA-256 hentar ekki eitt og sér til að geyma aðgangsorð,
- salt má vera sýnilegt en á að vera einstakt og slembið,
- aðgangsorð þurfa hæga, sérhæfða aðferð eins og Argon2id, scrypt, bcrypt eða PBKDF2,
- HMAC notar leyndan lykil með tætifalli til að auðkenna skeyti,
- HMAC felur ekki skilaboðin,
- við þurfum að velja verkfæri eftir því hvort markmiðið er leynd, heilleiki, auðkenning eða örugg geymsla aðgangsorða.
Næst förum við yfir dreifilykla og RSA. Þá skoðum við hvernig hægt er að nota tvo lykla í stað þess að koma sameiginlegum leynilykli til beggja aðila fyrirfram.