- CS-EJ4404
- 7. Tiivistefunktiot (engl. HASH)
- 7.4 Autentikoitu tiiviste (HMAC)
Autentikoitu tiiviste (HMAC)¶
Osaamme nyt laskea tiivisteen mistä tahansa tietokoneen informaatiosta. Voimme varmistaa, että informaatiota ei ole muutettu vertaamalla annettua ja laskettua tiivistettä.
Lavennamme nyt osaamistamme. Opettelemme luomaan autentikaatiokoodin (engl. authentication code). Käytämme esimerkkeinä viestejä, mutta autentikaatiokoodin voi luoda kaikelle digitaaliselle informaatiolle. Tässä osiossa opimme, miten toimii tiivistepohjainen viestin autentikaatiokoodi (engl. hash-based message authentication code).
Kyseessä ei ole digitaalinen allekirjoitus, jonka opimme seuraavassa luentokokonaisuudessa.
Katsotaan, miten Bob käyttää tiivistettä:
Bob saa viestin: ”Olen maksanut Carolin syntymäpäiväkakun tarveaineet ja ne voi hakea lähikaupasta. Vakuutan tämän tiedon oikeaksi. Alice.”
Bob saa tiivisteen
885e37c2da9403e323488cac14a628282577902477453c0971c03a05e0cf98a6
.
# Tuodaan SHA2-256
from hashlib import sha256
from xip import alusta_t740
viesti, tavu_viesti, annettu_tiiviste, _ = alusta_t740()
# Lasketaan itse tiiviste
laskettu_tiiviste = sha256(tavu_viesti).hexdigest()
# Näytetään viesti
print("Viesti on :", viesti)
print("Laskettu tiiviste:", laskettu_tiiviste)
print("Annettu tiiviste :", annettu_tiiviste)
print("")
if annettu_tiiviste == laskettu_tiiviste:
print("Näyttäisi siltä että annettu tiiviste täsmää annettuun viestiin!")
else:
print("Näyttää siltä että joku on muuttanut viestiä tai annettu tiiviste on väärin!")
print("\nMutta mistä tiedän että lähettäjä on Alice?")
Autentikaatiokoodi (MAC)¶
Seuraavaksi opimme, miten Alice ja Bob voivat yhteisellä, etukäteen jaetulla salaisella avaimella varmistaa viestin eheyden ja autenttisuuden. Tällöin kukaan ulkopuolinen ei ole voinut muuttaa viestiä ilman, että se pystytään havaitsemaan.
Seuraavaksi tuotamme autentikaatiokoodeja. Käytämme autentikaatiokoodeja, jotka käyttävät SHA-2-tiivistefunktioita. Näitä kutsutaan HMAC:eiksi (engl. Hash-based Message Authentication Code).
Autentikaatiokoodin pituus on sama kuin käytetyn tiivistefunktion tuottaman tiivisteen pituus.
Informaation lähettävä osapuoli tuottaa informaatiosta salaisella avaimella ja tiivistefunktilla MAC:in. Informaatio on esimerkeissämme viesti. Informaation vastaanottaja pystyy varmistamaan viestin eheyden ja alkuperän tarkistamalla autentikaatiokoodin. Menetelmässä kummankin osapuolen on käytettävä samaa symmetristä avainta sekä tiivistefunktiota.
Seuraavaksi kokeillaan HMAC:in toimintaa käytännössä:
Alice tuottaa viestille salaisella avaimella ja SHA-256-tiivistefunktiolla autentikointikoodin (MAC). Bobille lähetetään viesti, tieto tiivistefunktiosta ja autentikointikoodi.
Bob varmentaa Alicen viestin eheyden ja alkuperän.
Auteentikaatiokoodin luonti¶
Alice luo viestille autentikaatiokoodin eli MAC:n käyttämällä salaista avainta ja SHA-256-tiivistefunktiota.
import hmac, hashlib
from xip import alusta_t740
# Alustetaan viesti ja avain.
viesti, tavu_viesti, annettu_tiiviste, salainen_avain = alusta_t740()
# Tuotetaan MAC salaisella avaimella ja sha-256 tiivistefunktiolla
autentikaatiokoodi = hmac.new(salainen_avain, tavu_viesti, hashlib.sha256)
print("Alice luo autentikaatiokoodin viestille käyttäen etukäteen sovittua avainta ja SHA-256 tiivistefunktiota.\n")
print("Viesti :", viesti)
print("Viestin pituus : {} bittiä".format(len(viesti)*8))
print("MAC :", autentikaatiokoodi.hexdigest())
print("MAC pituus : {} bittiä".format(len(autentikaatiokoodi.digest())*8))
print("Salainen avain :", salainen_avain)
print("Avaimen pituus : {} bittiä".format(len(salainen_avain)*8))
Edellisestä tulosteesta näemme että:
Viestin pituus on 968 bittiä.
autentikaatiokoodin (MAC) pituus on 256 bittiä.
Avaimen pituus on 2048 bittiä (tähän palataan pian).
Viestin pituus ei vaikuta autentikaatiokoodin eli MAC:in pituuteen.
Avaimen pituus ei vaikuta MAC:in pituuteen.
Eri autentikaatiokoodit asettavat käytetylle avaimelle joitain vaatimuksia. HMAC:n tapauksessa avaimen pituudessa on huomioitava muutama asia:
HMAC:in avain ei saa olla lyhyempi kuin autentikaatiokoodi. Tämä luo hyökkäysvektorin, jonka haluamme välttää.
Jos MAC:in avain on pidempi kuin autentikaatiokoodi, lasketaan avaimesta ensin tiiviste, jota sen jälkeen käytetään avaimena.
Auteentikaatiokoodin varmistaminen¶
Bob saa Alicelta viestin, autentikointikoodin ja tiedon käytetystä tiivistefunktiosta. Nyt Bob kykenee tarkistamaan, pystyykö hän tuottamaan viestistä salaisella avaimella ja annetulla tiivistefunktiolla saman autentikaatiokoodin, jonka Alice lähetti hänelle.
import hmac, hashlib
from xip import alusta_t741
# Bob vastaanottaa viestin, autentikaatiokoodin ja käytetyn tiivistefunktion.
alicen_viesti, alicen_autentikaatiokoodi, _, tiivistefunktio = alusta_t741()
# Bob kaivaa esiin salaisen avaimen säilöstä
_, _, salainen_avain, _ = alusta_t741()
# Koko salainen avain avaimeksi, voidaan muuttaa salainen_avain[1:] tai muulla rajoituksella
avain = salainen_avain[:]
# Bob laskee viestistä autentikaatiokoodin
print("Bob laskee autentikaatiokoodin viestille käyttäen etukäteen sovittua avainta ja SHA-256 tiivistefunktiota.\n")
bobin_laskema_autentikaatiokoodi = hmac.new(avain, alicen_viesti.encode(), tiivistefunktio )
# Näytetään tuloksia
print("Viesti :", alicen_viesti)
print("Alicen MAC :", alicen_autentikaatiokoodi.hexdigest())
print("Bobin MAC :", bobin_laskema_autentikaatiokoodi.hexdigest())
print("Alicen avain :", salainen_avain)
print("Bobin avain :", avain)
print("")
# Tarkistetaan täsmäävätkö autentikaatiokoodit
if bobin_laskema_autentikaatiokoodi.digest() == alicen_autentikaatiokoodi.digest():
print("Varmistus meni oikein!")
print("Viestistä laskettu autentikaatiokoodi täsmää Bobin Alicelta saamaan autentikaatiokoodiin.")
print("Nyt olemme varmoja siitä, että saamamme viesti ja autentikaatiokoodi ovat oikeita!")
else:
print("Varmistus epäonnistui!")
print("Joko viestin sisältö on muunnettu tai lähettäjä ei ole Alice")
print("\nNäin olemme pyrkineet varmistamaan viestin eheyden ja alkuperän!")
Näin Bob on varmentanut viestin eheyden ja alkuperän!
Loppuyhteenveto¶
Muista
Pythonin hmac
-funktio käytti verrattain pitkään MD5-tiivistefunktiota autentikointikoodin luomiseen.
MD5:n heikko kyky sietää tiivisteiden törmäyksiä on tunnettu jo varsin pitkään. Siitä huolimatta Pythonissa on käytetty kryptografisesti heikkoa tiivistefunktiota.
Tämä on tietenkin ristiriidassa aikaisempaan suositukseen luottaa valmiisiin kirjastoihin. Valitettava totuus on se, että henkilöt, jotka vastaavat kryptografisista menetelmistä kyberturvallisuuden sovelluksissa, joutuvat itse varmistamaan kryptografisten funktioiden ajantasaisuuden ja oikean toiminnan.
Olemme tässä moduulissa oppineet, miten tiivistefunktiot toimivat ja mihin niitä käytetään. Sen lisäksi olemme oppineet niiden ominaisuuksista:
Tiivistefunktiot tuottavat tiivisteitä.
On olemassa eri tiivistefunktioiden ”perheitä” ja tiivisteiden pituuksia (bitteinä).
Tiivistefunktion on oltava yksisuuntainen. Sille ei saa olla olemassa käänteisfunktiota.
Tiivistefunktiot voivat tuottaa törmäyksiä.
Tiivisteiden törmäys tarkoittaa, että kaksi tai useampi alkukuva tuottaa saman tiivisteen.
Huono tiivistefunktio mahdollistaa törmäysten systemaattisen tuottamisen.
Osaamme nyt myös tuottaa autentikaatiokoodeja (MAC). Tähän tarvitaan avaimellisia tiivistefunktiota ja salainen avain. MAC suojaa sekä tiedon autenttisuutta että eheyttä.
Koska Alice ja Bob käyttävät samaa avainta, on kyseessä symmetrinen avain. Seuraavassa opetusmoduulissa opimme, miten julkisen avaimen menetelmä toimii. Tällöin Alice käyttää omaa salaista avaintaan tuottaessaan digitaalisen allekirjoituksen. Julkisen avaimen menetelmässä Bob pystyy varmistamaan Alicen julkisella avaimella, että digitaalinen allekirjoitus on oikea.
Kun olemme oppineet epäsymmetristen avainten perusteet, pääsemme opetusmoduulissa 9 rakentamaan julkisen avaimen infrastruktuuria. Tällöin opimme, miten voimme luottaa allekirjoitukseen jonka tekijää emme entuudestaan tunne.
Seuraavaksi perehdymme julkisen avaimen menetelmiin (engl. public key). Julkisella avaimella on mahdollista tuottaa jaettu salaisuus turvattoman kanavan, esimerkiksi sähköpostin, välityksellä. Tällaista jaettua salaisuutta voidaan hyödyntää esimerkiksi luodessa ja varmistaessa digitaalisia allekirjoituksia.