python kryptausopas - it.lut.fi · python – kryptausopas lty 5 hash-funktio luvun pituus md2 128...

24
PYTHON - KRYPTAUSOPAS Lappeenrannan teknillinen yliopisto 2007 Jussi Kasurinen

Upload: phamhuong

Post on 01-Mar-2019

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

PYTHON

-

KRYPTAUSOPAS

Lappeenrannan teknillinen yliopisto 2007 Jussi Kasurinen

Page 2: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

1

Johdanto

Tässä oppaassa esitellään Python-ohjelmointikielen salaus- ja varmennustekniikoidenkirjastomoduuli Python Cryptography Toolkit. Oppaassa oletetaan, että ymmärrät Python-ohjelmointikielen perusasiat, jotka on opetettu mm. Python-ohjelmointioppaassa [1], mutta etvälttämättä tarvitse aiempaa tietoa salausalgoritmeista. Huomaa myös, että oppaan luvut 2(Huomioita PCT-moduulista) - 7 (Muita työkaluja) on vapaasti käännetty alkuperäisenkirjastomoduulin mukana toimitettavasta manuaalista [2], mutta siihen on lisätty mukaan myösuusia esimerkkejä sekä tarpeen mukaan täydentävää tekstiä. Kappaleet, joiden varsinaistaasiasisältöä on muokattu, tai jotka ovat tätä opasta varten kirjoitettua täydentävää materiaalia, onmerkattu tekstin vasemmassa reunamarginaalissa olevalla merkinnällä ”LTY”.

Asennus

Python Cryptography Toolkit (PCT) asennetaan tietokoneelle erillisenä pakettina Python ImagingLibraryn tai Py2Exe-pakkaajan tavoin. Tämä tarkoittaa siis sitä, että aloittaaksesi kryptauskirjastollatyöskenetelyn, tarvitset verkkoyhteyden tietokoneeseesi. Tämän jälkeen toimi seuraavalla tavalla:

• Hae Python Cryptography Toolkit uusin versio (kirjoitushetkellä 2.0.1) osoitteestahttp://www.voidspace.org.uk/python/modules.shtml#pycrypto. Valitse oikea pakettikäyttämäsi tulkin version mukaisesti.

• Asenna PCT normaalin lisäkirjaston asennuskaavan mukaisesti. Asennus on suoraviivainen,mutta mikäli tarvitset ohjeet asennusta varten, löytyy sellaiset esimerkiksi Python-grafiikkaohjelmointioppaasta [3]. Oppaan ohjeissa asennetaan Python Imaging Library,mutta asennusvaiheet ja tapahtumat ovat muutoin täysin samat.

• Asennuksen jälkeen käynnistä Python-tulkki ja kirjoita interaktiiviseen ikkunaankomento ”import Crypto” – huomaa iso C-kirjain. Mikäli tulkki ei antanutvirheilmoitusta, olet asentanut PCT:n onnistuneesti ja voit jatkaa eteenpäin oppaan kanssatyöskentelyä.

Page 3: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

2

Huomioita PCT-moduulista

Alkuperäinen lähde Python Crypthography Toolkit Manual, http://www.amk.ca/python/writing/pycrypt/

Python Cryptography Toolkit on kehitetty toimimaan luottavana sekä vakaana alustana, jonkapäälle on mahdollista kirjoittaa ohjelmia, jotka vaativat tiedon salaukseen tai varmentamiseentarvittavia funktioita.

Keskeinen tavoite moduulin toteutuksessa onkin ollut toteuttaa yksinkertainen sekä yhdenmukainenrajapinta toistensa kaltaisille funktioille. Esimerkiksi kaikki salausobjektit (block cipher objects)sisältävät samannimiset metodit sekä palautusarvot sekä tukevat samoja palautemoodeja.Tarkastuslukujen (hash) laskemiseen käytettävillä funktioilla on tekniikoista johtuen erilaisetkäyttöliittymät, mutta niiden yleinen toiminta on pyritty yhdenmukaistamaan. Lisäksi osallefunktioista on määritelty toiminta PEP (Python Enhancement Proposal)-dokumentteina [4,5].

Tällä toimenpiteellä pyritään helpottamaan salausalgoritmien korvaamista uudemmilla javarmemmilla algoritmeilla. Jos olet aiemmin luonut ohjelman, joka käyttää esimerkiksi DES-algoritmia salauksen toteuttamiseen, voit helposti vaihtaa sen esimerkiksi AES-algoritmiinmuuttamalla sisällytyskäskyn muodosta

from Crypto.Cipher import DES

muotoon

from Crypto.Cipher import AES

Tämän lisäksi riittää kun korvaat vielä käskyt DES.new() käskyllä AES.new(). Myös omienmoduulien kirjoittaminen on helppoa: voit esimerkiksi toteuttaa moduulin joka käyttää tätärajapintaa ja täten luoda salauksen, joka hyödyntää usean salausalgoritmin yhdistelmiä.

Osa moduuleista on toteutettu C-kielellä laskentanopeuden parantamiseksi; muut taas Pythonillamuokattavuuden helpottamiseksi. Yleisesti tämä tarkoittaa sitä, että matalan tason laskentafunktiot,kuten salakirjoittajat (ciphers) sekä varmistussummalaskurit (hash functions) on toteutettu C-kielellä, kun taas niiden käyttämiseen tarkoitetut – vähemmän laskentatehoa vaativat - funktiot ontoteutettu Pythonilla. Kannattaa myös huomioida, että kun puhumme nopeudesta, tarkoittaa se 500MHz Pentium 2 –koneella laskettuja suoritusaikoja. Tarkka nopeus tietenkin riippuu monestamuustakin tekijästä, mutta oppaan aikavertailut ovat suuntaa antavia.

Moduulien ohjelmakoodi on vapaasti muokattavissa ja levitettävissä. Kuitenkaan se ei vielä tarkoitasitä, että kaikki koodi olisi vapaasti käytettävissä: osa tähänkin moduuliin sisällytetyistäsalausmekanismeista on patentoitu kaupallista käyttöä varten, joten mikäli toteutat kaupalliseen

Page 4: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

3

levitykseen tarkoitettua projektia, varmista että käyttämäsi salausmekanismi ei kuulu näihin.Muussa tapauksessa joudut itse sopimaan patentinhaltijan kanssa asiasta. Lisäksi joissain maissa(esim. Yhdysvallat) salausalgoritmien käyttöä ja levitystä valvotaan kansallisilla lailla, jotenvarmista lisäksi ettet riko paikallisia lakeja. Suomessa kyseisiä rajoitteita tai lakeja ei tiettävästi ole,joten voit vapaasti käyttää ja levittää tekemiäsi ohjelmia kunhan et riko kaupallisen käytönlisenssiehtoja.

Myöskään salausalgoritmien salauksen varmuus ei ole itsestäänselvyys. Osa salausalgoritmeista ononnistuttu murtamaan joko yksittäistapauksissa tai täydellisesti, tehden salauksesta triviaalin. Tästäpuhutaan oppaassa myöhemmin lisää, mutta tärkeintä kaikilla näillä varoituksilla on tarkoitus:mikäli työskentelet ohjelman kanssa jonka haluat olevan oikeasti turvallinen, niin käytä ennemminhieman aikaa taustatutkimukseen ennen kuin aloitat työstämään projektiasi huonoilla tai viallisillaosilla.

Page 5: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

4

Crypto.Hash: Tarkastuslukufunktioita

Alkuperäinen lähde Python Crypthography Toolkit Manual, http://www.amk.ca/python/writing/pycrypt/

Tarkastuslukufunktiot (hash-functions) ottavat syötteenään satunnaisen mittaisia merkkijonojalähtöarvoina ja tuottavat tietyn mittaisia tulosjonoja eli tarkastussummia, joiden arvo riippuuannetusta lähtöarvosta. Tarkastulukufunktiot toimivat siten, että annettua lähtöarvoa ei pitäisi pystyäpäättelemään palautetusta tulosjonosta, mutta lähtöarvon oikeellisuus pystytään varmentamaanpalautetun tarkastusluvun avulla. Yksinkertaisimmillaan tämä tarkoittaa vaikkapa funktiota, jokalaskee yhteen kaikki merkkijonon bittiarvot, ja ottaa tuloksesta jakojäännöksen arvolla 256:

>>> sana = "Sihijuoma">>> tulos = 0>>> for i in range(0,len(sana)):

tulos = tulos + ord(sana[i])

>>> tarkastusluku = tulos % 256>>> tarkastusluku169>>>

Esimerkissä syötteenä antamallemme merkkijonolle ”Sihijuoma” saatiin tarkastusluvuksi arvo 169.Vastaavasti jos olisimme toteuttaneet laskennan merkkijonolle ”sihijuoma” (pieni s-kirjain), olisitulos ollut 201, ja merkkijonolle ”Ketsuppijäätelö” 194. Kuten huomaamme, yhdessäkääntapauksessa emme pysty päättelemään, mikä alkuperäinen merkkijono oli, sekä samalla todistimme,että yhden merkin muuttaminen vaihtaa tarkastusluvun arvoa merkittävästi.

Ollakseen varma sekä luotettava, on tarkastuslukufunktiot toimittava siten, että kahden samantarkastusluvun tuottavan lähtöarvon löytäminen, tai tarkastusluvun arvon avulla tekstingeneroiminen on vaikeaa. Vaikka yksinkertainen esimerkkimme ei täytäkään kumpaakaan ehtoa, onse silti perusajatukseltaan oikea. Jos taas haluamme käyttää turvallisia tarkastuslukufunktioita, niinesimerkiksi algoritmeja MD2, MD5, SHA, ja HAVAL on yleisesti pidetty turvallisina laskureina.

Tarkastuslukufunktioita käytetään tavallisesti tiedostonsiirroissa varmennuslukuina sekä julkistenavainten yhteydessä digitaalisina allekirjoituksina. PCT tukee tällä hetkellä seuraaviatarkastuslukualgoritmeja:

Page 6: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

5

Hash-funktio Luvun pituusMD2 128 bittiäMD4 128 bittiäMD5 128 bittiäRIPEMD 160 bittiäSHA 160 bittiä

Kaikilla tarkastuslukufunktioilla on sama käyttöliittymä. Kun haluttu funktio on sisällytettykäskyllä from Crypto.Hash import nimi, voidaan funktiolla new() luoda uusitarkastuslukuobjekti. Tälle objektille tämän jälkeen syötetään lähtöarvo update() –metodilla.Tarkastusluku voidaan ottaa ulos joko tavallisena merkkijonona tai heksa-arvoina metodeilladigest() ja hexdigest(). Funktiolle new() voidaan myös suoraan kutsussa antaa parametrinalähtöarvo, joka samalla muutetaan tarkastusluvuksi.

Ohessa esimerkki käyttäen MD5-algoritmia:

>>> from Crypto.Hash import MD5>>> tarkastusluku = MD5.new()>>> tarkastusluku.update('Kurjenmutka')>>> tarkastusluku.digest()'\x06Kk\x8d~\xe1>\xc0\xb1K\x96;\xf7o_\xb6'>>> tarkastusluku.hexdigest()'064b6b8d7ee13ec0b14b963bf76f5fb6'>>>

Käyttöliittymien samankaltaisuudesta johtuen voimme toteuttaa saman uudelleen vaikkapa SHA-algoritmilla:

>>> from Crypto.Hash import SHA>>> tarkastusluku = SHA.new()>>> tarkastusluku.update('Hanhivaara')>>> tarkastusluku.digest()'\x9d\x06x\xb5Xb,\xb6\x133\xfb\xbd\xd2-\xe5\xc4\xf9\xa7\x91\xad'>>> tarkastusluku.hexdigest()'9d0678b558622cb61333fbbdd22de5c4f9a791ad'>>>

Huomioi, että SHA tuottaa pidemmän tarkastusluvun kuin esimerkiksi MD5. Tässä vielä kootustitarkastuslukufunktioiden metodit ja muuttujat:

digest_sizeInteger-arvo; Tämä arvo sisältää tiedon siitä, kuinka pitkän tarkastusluvun funktio palauttaa.Arvon muuttaminen ei vaikuta funktion toimintaan, vaan on lähinnä tarkoitettunopeuttamaan tarkastusluvun koon hakemista.

copy()Palauttaa kopion alkuperäisestä tarkastuslukuobjektista. Tämän objektin muuttaminen eivaikuta alkuperäisen objektin arvoihin.

digest()Palauttaa objektille annetusta lähtöarvosta tarkastusluvun merkkijonona. Objekti itsessään eimuutu funktion seurauksena, joten voit käyttää objektia uudelleen vaihtamalla lähtöarvojaupdate() –metodilla ja kutsumalla digest() –metodia uudelleen..

Page 7: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

6

hexdigest()Sama kuin digest(), mutta palauttaa tarkastusluvun heksa-arvoina. Tämän vuoksimerkkijono on aina kaksi kertaa pidempi kuin digest() –metodin palauttama.

update(arg)Antaa tarkastuslukuobjektille lähtöarvoksi parametrin arg.

new(arg)Luo uuden tarkastuslukuobjektin. Ottaa vastaan myös parametrin arg, joka annetaan suoraanlähtöarvoksi.

Huomioita turvallisuudesta

Tarkastusluku-algoritmit pystytään rikkomaan kehittämällä algoritmi, joka generoi annettuatarkastuslukua vastaavia lähtöarvoja, tai tuottaa viestejä, joilla on sama tarkastusluku. Voimmeosoittaa tämän ongelman käytännön esimerkin avulla:

Hannu ja Aku käyttävät digitaalista allekirjoitusta vahvistaakseen sopimuksen. Aku laskeesopimuksen tekstistä tarkastusluvun ja allekirjoittaa sen omalla salatulla avaimellaan. Tämänjälkeen Hannun tarvitsisi ainoastaan korvata Akun kirjoittaman sopimuksen teksti sellaisella, jokaantaa saman tarkastusluvun, eikä Aku pystyisi mitenkään todistamaan, että sopimuksen tekstiä onmuutettu. Tällaisen tekstin löytäminen vaatisi Hannulta 2b-1 testiä; b on tarkastusluvun pituusbitteinä.

Jos Hannu pystyy tuottamaan kaksi tekstiä, jotka antavat saman tarkastusluvun mutta ei pystyvaikuttamaan suoraan tarkastusluvun arvoon, voisi hän valita kaksi tekstiä joiden merkitys on hyvinerilainen. Ensin hän allekirjoituttaisi Akulla normaalin sopimuksen, vaikkapa ”Ajan Hannunnurmikon mikäli en ui jouluaattona järven yli”, ja jälkikäteen vaihtaa tekstiksi toisentuloksen ”Annan taloni Hannulle ellen ui jouluaattona järven yli”. Tämä olisi kaiken lisäksiHannulle helpompaa: keskimäärin tarvitsisimme ainoastaan 2b/2 yritystä. Jälleen kerran Aku eipystyisi todistamaan, että allekirjoitettua sopimusta on muutettu. Aku voisi tietenkin turvatatilanteensa sotkemalla algoritmin syöttämällä tekstiin satunnaisesti generoidun lisärivin, jonkasäilyttämällä hän pystyisi todistamaan sopimuksensa aitouden.

Tämä ei vielä varsinaisesti ole huolenaihe PCT:n tarkastuslukualgoritmien kanssa. PCT:n käytössäolevista viidestä tarkastuslukualgoritmista yhtäkään ei ole vielä onnistuttu trivialisoimaan. MD2:tavastaan ei ole olemassa tunnettuja hyökkäyksiä, mutta sen suoritusnopeus 1250 K/sek. tekee siitävarsin hitaan algoritmin. MD4 on nopeampi – 44,500 K/sek – mutta se on onnistuttu osittainmurtamaan. MD4 sisältää kolme iteratiivista sekoituskierrosta: näistä kaksi on jo pystyttymurtamaan mutta täyttä algoritmia ei vielä toistaiseksi saatu täysin rikottua. MD5 on MD4-algoritmista paranneltu versio ja se sisältää neljä iteraatiokierrosta. Tästäkin algoritmista yksikierros on saatu murrettua. Siitäkin huolimatta MD5:ttä pidetään edelleen turvallisena, mutta siltiuseat tahot ovat siirtymässä kohti SHA-algoritmia, jolle ei vielä toistaiseksi ole olemassa tunnettujahyökkäyksiä lukuun ottamatta SHA:n ensimmäisiä versioita, mutta nämä puutteet on myöhemminkorjattu. Lisäksi koska MD5-algoritmin suoritusnopeudeksi on mitattu 35,500 K/sek ja SHA:lle21,000 K /sek, ei varsinaisesti ole mitään syytä käyttää heikompia algoritmeja.

.

Page 8: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

7

Crypto.Cipher: Salausfunktioita

Alkuperäinen lähde Python Crypthography Toolkit Manual, http://www.amk.ca/python/writing/pycrypt/

Salausalgoritmit (encryption algorithms) toimivat siten, että ne muuntavat niille annetunsyötetekstin (selkoteksti, plaintext) jonkin kaavan ja avaimen (variable key) avulla salatuksitekstiksi (salateksti, ciphertext). Salaus- ja purkuoperaatio on tarkoitus olla helppo ja nopeasuorittaa kumpaan tahansa suuntaan, mutta ainoastaan mikäli käyttäjällä on hallussaan salauksessakäytetty avain. Tämä tarkoittaa tietenkin sitä, että salausalgoritmi on luotettava ja varma silloin, kunmahdollisia avaimia on suuri määrä ja käytettävää avainta ei pystytä päättelemään tuotetustasalatekstistä. Yksinkertainen esimerkki kryptauksesta voisi olla algoritmi, joka vaihtaa kirjaimiaaakkosissa eteen- tai taaksepäin tietyn verran:

>>> teksti = "Karhuvuori">>> avain = 3>>> salattu = "">>> for i in range(0,len(teksti)):

salattu = salattu + chr(ord(teksti[i])+avain)

>>> salattu'Ndukxyxrul'>>>

Tässä tapauksessa selkoteksti on siis “Karhuvuori”, salausavain “3” ja tuloksena saatava salateksti“Ndukxyxrul”. Tietenkään tällainen salaus ei ole kovin tehokas, koska potentiaalisia avaimia onainoastaan 54 kappaletta. Lisäksi kirjainten suhteellinen määrä pysyy vakiona: jos tiedämme milläkielellä teksti on salattu, voimme muutaman kokeilun avulla purkaa tekstin kunhan ensinpaikallistamme symbolit, jotka vastaavat yleisimmin käytettyjä kirjaimia, kuten a,e,l,n,k ja m.Luonnollisesti paremmat salausalgoritmit ottavat tämänkin huomioon, esimerkiksi muuttelemallaavainta jonkin kaavan mukaisesti:

>>> teksti = "Peikonhammas">>> avain = 3>>> salattu = "">>> for i in range(0,len(teksti)):

salattu = salattu + chr(ord(teksti[i])+avain)avain = avain + 1

>>> salattu'Sinqvvqkxyn\x81'

Page 9: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

8

Nyt luotua salatekstiä on jo paljon vaikeampi tulkita. Ollakseen tehokas, täytyy salausalgoritmistayleensäkin olla mahdollisimman vaikeaa päätellä mitään tietoa selkotekstistä ilman avainta. Tämätarkoittaa myös sitä, että salaukselle ei tulisi olla olemassa mitään tehokkaita hyökkäysmenetelmiä,ja että ainoa tapa avata salateksti ilman avainta on kokeilla kaikkia mahdollisia kombinaatioita.Koska avainkombinaatioita tavallisesti on vähintään 256 tai 2128 kappaletta, ei tämä aiheuta ongelmia.Kannattaa kuitenkin huomata, että 256 avaimen algoritmit voidaan nykyään periaatteessa purkaajärkevässä ajassa (muutama tunti - muutama päivä) sitä tarkoitusta varten suunnitellullarinnakkaislaskentatietokoneella.

Kehittyneempiä salausalgoritmeja ovat lohkonsalausalgoritmit (block ciphers), jotka ottavatsyötteinä vastaan määrätyn kokoisia syötteitä. Nämä syötteet ovat normaalisti kokoluokkaa 8 tai 16tavua. Yksinkertaisimmillaan lohkonsalaajat toimivat siten, että ne ottavat tekstistä peräkkäisiälohkoja, ja salaavat ne normaalin salausalgoritmin tavoin. Tätä toimintatapaa sanotaan ElectronicCode Book (ECB)-tilaksi. ECB on kuitenkin vaarallinen, koska tällöin peräkkäiset samansisältöisetrivit – kuten kommenttimerkeillä piirretyt laatikot lähdekoodissa – tuottavat samanlaisia lohkojasalatekstiin. Tällöin tekstin purkamista yrittävillä henkilöillä on jo jonkinlainen lähtökohta tekstinpurkamiseen. Tätä torjutaan tavallisesti takaisinsyöttötiloilla, joissa edellisen lohkon tulos vaikuttaaseuraavaan, eikä kaksi peräkkäistä lohkoa tällöin saa koskaan samaa arvoa.

Muita toimintatiloja ovat mm. Cipher Block Chaining (CBC) sekä Cipher FeedBack (CFB). CBCpakkaa tietoa edelleen lohkoissa, ollen ainoastaan hieman ECB-menetelmiä hitaampi. CFBpuolestaan pakkaa tietoa merkki kerrallaan, ollen huomattavasti muita hitaampi. CBC –tilattarvitsevat alustuksessa lähtöarvon, jota käytetään ensimmäisen lohkon salaamisessa.

Python Cryptography Toolkit tukee tällä hetkellä seuraavia lohkonsalausalgorimeja. Ne kaikkilöytyvät kirjastomoduulin Crypto.Cipher sisältä:

Salaus Avaimen koko/Lohkon kokoARC2 Vaihtelee/8 tavua

Blowfish Vaihtelee /8 tavuaCAST Vaihtelee /8 tavuaDES 8 tavua/8 tavua

DES3 (Triple DES) 16 tavua/8 tavuaIDEA 16 tavua/8 tavuaRC5 Vaihtelee /8 tavuaAES 16, 24, tai 32 tavua/16 tavua

On myös olemassa tietovirransalaukseen käytettäviä salausalgoritmeja (stream ciphers), jotkaperiaatteessa ovat merkki kerrallaan salaavia lohkonsalausalgoritmeja. Näillä algoritmeilla lohkonkoko on aina 1 tavu, eikä niillä ole toimintatiloina kuin ainaostaan ECB.

PCT tukee seuraavia virransalausalgoritmeja:

Salaus Avaimen kokoXOR VaihteleeARC4 Vaihtelee

Page 10: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

9

ARC4 on lyhenne sanasta “Alleged RC4”. Tämä johtuu siitä, että oikea RC4-algoritmi on RSAData Security Inc. omaisuutta, mutta PCT:hen sisällytetty versio on siitä verkkoon vuotanutalgoritmiversio. Ei ole täysin varmaa, onko ARC4 oikeasti RC4, mutta salaus ei vaikuttaisi olevanhelposti purettavissa. Kannattaa kuitenkin pitää mielessä, että kyseinen implementaatio ei olevirallinen, eikä tällöin sen mahdollisia takaportteja tai muita ongelmia välttämättä tiedetä.

Salausalgoritmien toimintaa voimme testata myös esimerkin avulla:

>>> from Crypto.Cipher import DES>>> avain = DES.new('ABCDEFGH') #Huomaa avaimen 8 merkkiä>>> selko="Suo mulle hauta pohjassa meren,\kun vanhuuden peikko mun hyytävi veren.">>> len(selko)70>>> avain.encrypt(selko)

Traceback (most recent call last): File "<pyshell#42>", line 1, in <module> avain.encrypt(selko)ValueError: Input strings must be a multiple of 8 in length

>>> salateksti = avain.encrypt(selko+"XX")>>> salateksti'4t\x97b\xdf\xe7\xbbRd`\r`,\xca`x\x16\xdc\xb17\xf0\xa4ow&\xe7,$\xf81\x02\xa0R\x87\x07<\x9c9\xacu.8\xf3z1T=8]8\x96\x02L\x07\xb69\xde\xb4\x90\x91!\xce)\r\x85j\x16!A\\\x12p'>>> avain.decrypt(salateksti)'Suo mulle hauta pohjassa meren,kun vanhuuden peikko mun hyyt\xe4vi veren.XX'>>>

Kuten koodista ilmenee, on tekstiä salattaessa muistettava, että selkotekstin on oltava jaollinenkäytetyn algoritmin lohkon pituudella. Tässä tapauksessa käytimme DES-algoritmia, jonka lohkoon 8 tavua pitkä. Ensimmäinen yrityksemme salata 70 merkkiä pitkä teksti kaatui siihen, ettäviimeiseen lohkoon olisi jääny ainoastaan 6 tavua, joten jouduimme pidentämään sitä lisäämälläloppuun kaksi ”X”-kirjainta.

Kaikki salausfunktiot toimivat samanlaisella käyttöliittymällä. Kun olemme sisällytyksenyhteydessä päättäneet, mitä algoritmia käytämme, pystymme käyttämään seuraavia metodeja sekäattribuutteja salauksen säätelemiseen:

new(key, [ mode, IV])Luo uuden salausobjektin käyttäen alustusarvoina syötettyä avainta key sekä toimintatilaamode. Jos annettu tila on CBC tai CFB, täytyy lisäksi antaa aloitusarvo IV. Lisäksi joillainsalausalgoritmeilla on lisäksi omia lisäasetuksia, niistä voit lukea seuraavalta sivula.

block_sizeInteger-arvo, joka sisältää tiedon siitä minkä kokoisia lohkoja salausalgoritmi käyttää.

key_sizeInteger-arvo, joka kertoo minkä pituisia avaimia algoritmi käyttää. Jos arvo on 0, onavaimen koko vaihteleva.

IVSisältää lähtöarvon jota käytetään lohkojen salauksessa. Alustuksen jälkeen sisältääaloitusarvon, salauksen jälkeen uusimman generoidun. Tätä arvoa et voi muuttaa käsin.

Page 11: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

10

decrypt(string)Purkaa annetun merkkijonon string salauksen objektiin tallennetulla avaimella. Annettavanmerkkijonon tulee aina olla salausalgoritmin käyttämän lohkon koon moninkerta. Palauttaaselkotekstin merkkijonona.

encrypt(string)Salaa merkkijonon string käyttäen salausobjektille annettua avainta. Syötettävänmerkkijonon tulee olla käytetyn salausalgoritmin lohkon koon moninkerta.Virtasalausalgoritmit ottavat vastaan minkä pituisen tekstin tahansa. Palauttaa salatekstinmerkkijonona.

Algoritmikohtaisia attribuutteja

RC5-algoritmin yhteydessä voimme käyttää normaalien alustusparametrien lisäksi seuraavialisäparametreja:

• version: Mitä salausalgoritmin implementaatiota käytetään. Ainoa PCT:hen toteutettuversio on tällä hetkellä 1.0, eli ainoa sopiva arvo on 0x10.

• wordsize: Minkä pituisia sanoja käytetään; 16 ja 32 ovat ainoat sopivat arvot.. Yleisestipidempi on parempi, joten on suositeltavaa käyttää 32 merkin sanapituutta.

• rounds: Kuinka monta kierrosta salausalgoritmia ajetaan, yleisesti ottaen enempi onparempi. Arvo voi olla mitä tahansa väliltä 0 ja 255, joten arvon valinta perustuu lähinnänopeuden ja turvallisuuden väliseen valintaan.

Huomioita turvallisuudesta

Salausalgoritmit voidaan murtaa monella eri menetelmällä. Jos sinulla on salatekstiä ja tiedät (taipystyt arvaamaan) mitä sanoja tai lauseita teksti sisältää, voit sen avulla yrittää known-plaintext-hyökkäystä. Toisaalta, jos taas pystyt valitsemaan tekstin, joka salataan sinulle tuntemattomallaavaimella, pystyt analysoimaan avaimen arvon ja paljastamaan esimerkiksi jonkun henkilökohtaisenavaimen. Tätä kutsutaan chosen-plaintext-hyökkäykseksi.

DES (5100 K/sek) käyttää 56-bittistä avainta; tämän kokoinen avain on käymässä liian pieneksiollakseen varmasti turvallinen. Arviolta miljoona dollarilla riittää helposti supertietokoneeseen, jokapystyy muutamassa tunnissa murtamaan 56-bittisiä avaimia. Tähän operaatioon tarvitaan kuitenkinkeskimäärin 243 operaatiota, joten tavallisilta tietovarkailta olet edelleen turvassa. Mikäli kuitenkinhaluat suojautua kaikkia tilanteita varten, voit luonnollisesti käyttää DES3-salausta (1830 K/sek),joka käyttää 112- tai 168-bittisiä avaimia.

Myöskään IDEA-algoritmia (3050 K/sek) vastaan ei ole olemassa julkisesti tunnettuja hyökkäyksiä,vaikka algoritmi onkin ollut olemassa jo kauan. Lisäksi ARC2 (2160 K/sek), ARC4 (8830 K/sek),Blowfish (9250 K/sek), CAST (2960 K/sek) ja RC5 (2060 K/sek) ovat edelleen turvallisia, mutta neovat edelleen melko uusia algoritmeja, joten niiden suojausongelmia ei välttämättä vielä ole edestutkittu tarkkaan.

AES-algoritmi valittiin US National Institute of Standards and Technology:n testeissä kuudenkilpailijan joukosta tehokkaimmaksi ja turvallisimmaksi, joten sitä voidaan pitää ainakin melkohyvänä vaihtoehtona. Lisäksi sen salausnopeus (7060 K/sek) on suhteellisen nopea.

Page 12: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

11

Crypto.Protocol: Salausprotokollia

Alkuperäinen lähde Python Crypthography Toolkit Manual, http://www.amk.ca/python/writing/pycrypt/

Crypto.Protocol.AllOrNothing

Tämä moduuli sisältää toteutuksen kaikki-tai-ei-mitään-tyyppisille pakettimuunnoksille. Nämäpakettimuunnokset toimivat siten, että lähdeaineisto pakataan paketteihin, jotka kaikki pitää saadavastaanotettua ennen kuin salattu aineisto voidaan muuntaa takaisin alkuperäiseen muotoon. Tällöinpakettien rikkoutuminen, muunteleminen tai häviäminen estää viestin vastaanottamisen.

Kaikki-tai-ei-mitään-paketit eivät varsinaisesti ole salattuja, vaikka niiden yhteydessä käytetäänkinlohkonsalausalgoritmeja. Salausavain näet luodaan satunnaisesti ja se on helposti pääteltävissäpakettien sisällöstä.

Python Cryptography Toolkitin kaikki-tai-ei-mitään-menetelmän määrittelevä kirjasto sisältääseuraavat rakenteet:

class AllOrNothing(ciphermodule, mode=None, IV=None)Luokkarakenne joka määrittelee pakettimuunnoksen.

ciphermodule määrittelee käytettävän salausalgoritmin. Lisäparametrejä mode ja IV voidaan käyttäätarvittaessa salauksen tarkempaan määrittelyyn. Ciphermodule voi olla mikä tahansa edellisessäluvussa määritellyistä salausalgoritmeista.

digest()Suorittaa update()-metodilla syötetylle lähdeaineistolle kaikki-tai-ei-mitään pakkauksen.Tuottaa listan merkkijonoja, jossa yksi jono vastaa yhtä pakettia.

reset(text = "")Tyhjentää moduulin muistin.

undigest(mblocks)Purkaa paketit selkotekstiksi. Parametri mblocks on oltava lista, jossa yksi listan alkio vastaayhtä pakettia. Palauttaa selkokielisen merkkijonon.

update(text)Syöttää parametrilla text lähdeaineiston moduulille pakkausta varten.

Page 13: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

12

Crypto.Protocol.Chaffing

Karsiminen ja sotkeminen (winnowing ja chaffing) on tekniikka, jolla pystymme parantamaanverkossa siirrettävän tiedon turvallisuutta joutumatta käyttämään raskaita salausalgoritmeja.Lyhyesti ajatus perustuu siihen, että otamme joukon varmennettuja paketteja jotka haluammelähettää verkon yli, ja sotkemme lähetykseen sekaan ylimääräisiä paketteja, jotka haittaavatsalakuuntelijoita. Koska salakuuntelija ei pysty avaimella tarkastamaan mitkä paketit ovatvarmennettuja ja mitkä ylimääräisiä, voidaan ylimääräisillä paketeilla purkuoperaatiosta tehdälaskennallisesti mahdotonta.

Jos ajattelemme asiaa käytännön esimerkin kautta, niin olettakaamme, että Roope lähettää viestiäAkulle. Roope pakkaa viestit kaikki-tai-ei-mitään menetelmällä paketteihin ja laskee paketeillevarmennusluvut (message authentication code, MAC) etukäteen vaihdetulla varmennusavaimella.Lopuksi Roope vielä laittaa paketteihin järjestysnumerot ja lähettää ne Akulle.

Kun Aku saa paketit, hän ensin varmentaa paketit saamallaan avaimella. Jos MAC-luku on väärin,voi Aku suoraan hylätä paketin koska se ei kuulu lähetykseen. Ne paketit, joiden varmennusluku olioikein, Aku laittaa numerojärjestykseen, ja purkaa kaikki-tai-ei-mitään-paketoinnin saaden Roopenviestin.

Jos joku pystyisi kaappaamaan paketeista kopiot verkosta, olisi hänellä seuraavanlainen ongelma:Koska kaapparilla ei olisi Roopen ja Akun käyttämää varmennusavainta, ei kaappaaja tietäisi mikäpaketit ovat ylimääräisiä. Lisäksi, koska paketteja lähetettäisi useampi samalla järjestysnumerolla,joutuisi kaappaaja lisäksi kokeilemaan kaikkien pakettien kaikki kombinaatiot pystyäkseenmurtamaan salauksen. Ja lopulta, koska Roope käytti kaikki-tai-ei-mitään-paketointia, on viestihyödytön jos yksikin oikea paketti puuttuu.

Erityisen nerokasta menetelmässä on se, että se ei vaadi Akulta eikä Roopelta ylimääräisiävarmennuksia: Akulle riittää, kun hän tarkastaa jokaisen saamansa paketin varmennusavaimella.Myöskään Roopen ei tarvitse itse tehdä mitään valmisteluja, ylimääräisiä paketteja voidaan laittaasekaan automaattisesti vaikkapa 10 jokaista oikeaa pakettia kohti. Todennäköisyys, ettäsatunnaisesti arvottu varmennusluku vastaisi satunnaisesti arvottua sisältöä ja että molemmatvastaisi käytettyä varmennusalgoritmia, on olematon. Ja mikäli näin pääsisi käymään, voisi Roopelähettää viestin uudelleen.

Crypto.Protocol.Chaffing-moduulissa on seuraavat toiminnalliset rakenteet:

class Chaff(factor=1.0, blocksper=1)

Luokkarakenne, joka mahdollistaa ylimääräisten pakettien luomisen. Määrittelyssä annetaankaksi parametria: factor, jolla määrätään kuinka monelle alkuperäiselle paketille lisätäänylimääräisiä paketteja. Lukuarvo annetaan prosenttikertoimena välillä 0.0 ja 1.0; oletusarvoon 1.0. Arvolla blocksper määrätään, kuinka monta ylimääräistä pakettia jokaista oikeaapakettia kohti tehdään; oletusarvo on 1.

Page 14: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

13

Chaff- rakenteella on seuraavat metodit:

chaff(blocks)

Lisää ylimääräisiä paketteja viestiosioon. blocks on lista 3-tupleja, jotka ovat muotoa(sarjanumero,data,MAC). Metodi palauttaa samalla tavalla muotoillut listan, johon on lisättyalustusparametrien mukaisesti ylimääräisiä paketteja. Nämä paketit on luotu satunnaisestiannetun datan pohjalta.

__randnum(size)

Palauttaa satunnaisesti generoituja tavujoukkoja jotka ovat size tavua pitkiä. Moduuli luottaaomaan satunnaisgeneraattoriinsa, koska Pythonin oma generaattori ei ole riittävänsatunnainen, jonka seurauksena sillä luoduista paketeista voidaan nähdä tiettyjä toistuviakuvioita. Näiden kuvioiden takia pakettien tunnistaminen olisi helppoa, ja siksi modulinmukana toimitetaan oma tehokkaampi satunnaislukugeneraattori.

Page 15: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

14

Crypto.PublicKey: Julkisen avaimenalgoritmeja

Alkuperäinen lähde Python Crypthography Toolkit Manual, http://www.amk.ca/python/writing/pycrypt/

Tähän asti kaikki käyttämämme algoritmit ovat olleet yhteisen avaimen salausalgoritmeja. Tämätarkoittaa siis sitä, että viestit puretaan ja pakataan samalla avaimella, joten kaikkien viestejälähettävien ja vastaanottavien tulee tuntea tämä avain. Tähän juuri liittyykin seuraava ongelma: joshaluamme viestiä epäluotettavan verkon yli, voimme tietenkin salata viestimme, mutta kuinka alunperin aioimme saada avaimen perille jos oletamme että emme pysty sitä muilla keinoillasiirtämään? Emme voi lähettää avainta sähköpostilla, koska silloin se menisi selkokielisenä verkonyli, emmekä voi salata sitä toisella avaimella, koska tämäkin avain olisi lähetettävä selkokielisenä.Joutuisimme fyysisesti menemään paikan päälle viemään avaimen, ja tässä taas ei ole mitään järkeä.

Toinen vaihtoehto olisi käyttää julkisia salausavaimia hyödyntäviä salausalgoritmeja. Käytettäessäjulkisia avaimia, tuottaa salausalgoritmi kaksi erilaista avainta salauksia varten. Tiedon salaamistavarten luodaan julkinen avain (public key) ja purkamista varten salainen avain (private key).Salauksessa käytettävää julkista avainta voidaan jakaa verkossa vapaasti, kun taas salainen avaintulee säilyttää turvallisessa paikassa.

Jos joku haluaa lähettää sinulle varmennettua tietoa, hän voi salata viestin sinun julkisellaavaimellasi. Koska julkista avainta ei voida käyttää sillä luodun viestin purkamiseen, voitainoastaan sinä purkaa viestin omalla salaisella avaimellasi. Jotkin avainparit on lisäksi suunniteltusiten, että niillä voidaan tietoa salata ristiin molempiin suuntiin. Näitä julkisen avaimen algoritmejavoidaan käyttää tiedon lähettämisen lisäksi myös viestien allekirjoitukseen: koska avaimia voidaankäyttää ”ristiin” kumpaankin suuntaan - eli siten että salaisella avaimella salattua tietoa voidaanpurkaa julkisella avaimella – voit salata viestin salaisella avaimellasi, ja vastaanottaja varmentaaallekirjoituksen purkamalla sen julkisella avaimella.

Yleisesti julkisen avaimen salausalgoritmit toimivat siten, että salainen avain on vaikea päätelläjulkisesta avaimesta. Tämä ei kuitenkaan ole mahdotonta mikäli resursseja on riittävästi, joten ainoakeino suojautua tältä on tehdä avaimesta riittävän pitkä. On kuitenkin pidettävä mielessä, ettäavaimen pituus kannattaa valita siten, että avaimen koko on vielä kohtuullinen, jotta salauksenkäyttö olisi mielekästä.

Page 16: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

15

Python Cryptography Toolkit sisältää seuraavat julkisen avaimen algoritmit:

Algoritmi KäytettävyysRSA Salaus, varmennus/allekirjoitusElGamal Salaus, varmennus/allekirjoitusDSA varmennus/allekirjoitusqNEW varmennus/allekirjoitus

Useimmat näistä algoritmeista on kaupalliseen käyttöön patentoituja. Mikäli käytät niitäprojekteissasi, on suositeltavaa, että tarkastat niiden lisenssiehdot verkosta. Seuraavaksi tutustummetarkemmin RSA-salausalgoritmiin esimerkin avulla:

>>> from Crypto.Hash import MD5>>> from Crypto.PublicKey import RSA>>> from Crypto.Util.randpool import RandomPool

>>> lukulista = RandomPool()>>> RSAavain = RSA.generate(512, lukulista.get_bytes)>>> tarkastusluku = MD5.new("Joku porho kehui repineensä puukaupoilla niinpaljon tuohta että heikkolatvaisia puistatti.").digest()

>>> tunniste=RSAavain.sign(tarkastusluku,"")>>> tunniste(2488227805075508107753520610413128570898591316559627485443691432798630155485881303000064980473774493643623749643164057793284807040713852933375541262459784L,)

>>> RSAavain.verify(tarkastusluku,tunniste)1>>> RSAavain.verify(tarkastusluku[:-1],tunniste)0>>>

Ohjelma toimii siten, että me tarvitsemme kolme asiaa: Tarkastuslukualgoritmin, joksi valitsimmeMD5-algoritmin, avainalgoritmin, joksi valitsimme RSA:n sekä satunnaisgeneraattorin, joka otettiinmoduulista Crypto.Util.randpool. Ensin loimme uuden satunnaislukujoukon lukulista, ja annoimmesen RSA-algoritmille, joka loi uuden 512-bittisen avainparin. Tämän jälkeen teimmeselkotekstistämme MD5-tarkastusluvun. Seuraavaksi allekirjoitimme MD5-tarkastusluvun juuriluomallamme RSA-avaimella. Saatu tunniste on pitkä kokonaisluku, jonka lopuksi varmistimmeverify-funktiolla. Huomaa, että alempana jätimme pois tarkastusluvun viimeisen merkin, jollointunniste ei enää vastannut tarkastuslukua. Voimme testata ohjelman avainparien toimintaa vielätoisella esimerkillä:

>>> Julkinen = RSAavain.publickey()>>> selkoteksti = "Uniikki unikorni olikin korni koni.">>> viesti = Julkinen.encrypt(selkoteksti,"")>>> viesti('Mr\xa3\x84\xe8\xddfv\n\x020\xec\x1a\xce\xdaKf\xfe\x1c\x97\xca?\xfc|\x898\x8b\xa8\x1d\xe5\x8b\x1d)&&\xf0\x18\x124@=\xfd\x93\xd6\x9e{\xdek\xbfF]\xb4"lb$\xcd\xe4\x15\x8f\xdaL\xa8\x03',)>>> RSAavain.decrypt(viesti)'Uniikki unikorni olikin korni koni.'>>> allekirjoitus = RSAavain.decrypt("Uka Naakka")

Page 17: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

16

>>> allekirjoitus' \xa3m\xb0\xe9\x8f\x10uhj\x90>\xffj@\x18l\xfc\xba\xab\x94-\x89\xf3\x10\xbf\x96w\xe2\x96{n\xf5\x93J\xc4\xfc\xc1\xde\x9c\x97\x1b\xa5\xd2\x8fg\x98\x11 -\xb1\xe5\xbb\x98\xfe\xaf\xc9\x03\xe3\xf8F\xf5i\x0b'>>> Julkinen.encrypt(allekirjoitus,"")('Uka Naakka',)>>>

Nyt loimme RSAavaimesta julkisen avaimen, jolla salasimme viestin ”Vesihiisi”. Käyttämämmesalainen avain pystyi purkamaan viestin ilman ongelmia. Vastaavasti allekirjoitus sujui ilmanongelmia: ensin allekirjoitimme – eli periaatteessa purimme – tekstin ”Uka Naakka”, jonka julkinenavain onnistui kokoamaan – eli periaatteessa salaamaan – oikein siten, että allekirjoitus tulinäkyviin.

Julkisen avaimen salausalgoritmit sisältävät seuraavat yhteiset metodit:

generate(size, randfunc, progress_func=None)Luo uuden avainparin. Avaimet ovat kokoluokkaa size, ja niiden luomisessa käytetäänsatunnaislukugeneraattoria randfunc. Käytettävän satunnaislukugeneraattorin tulee toimiasiten, että se saa kutsussa parametrina yhden integer-arvon ja palauttaa näin montasatunnaista merkkiä. Esimerkkitehtävässä käyttämämme RandPool.get_bytes on hyvägeneraattori: Älä käytä Pythonin omaa random-satunnaislukugeneraattoria.

canencrypt()Palauttaa arvon True jos valittu avainalgoritmi pystyy purkamaan ja salaamaan tietoa.

cansign()Palauttaa arvon True jos valittu avainalgoritmi pystyy allekirjoittamaan tietoa..

decrypt(tuple)Purkaa tuplen salaisella avaimella, palauttaa merkkijonon.

encrypt(string, K)Salaa merkkijonon string salaisella avaimella. Parametrin K tulisi sisältää satunnaisiamerkkejä joita ohjelma voi käyttää salauksessa apunaan.

hasprivate()Palauttaa arvon True jos salausobjektille on syötetty salainen avain.

publickey()Palauttaa uuden julkisen avaimen jolla on mahdollista salata tietoa salaisella avaimellapurettavaksi.

sign(string, K)Allekirjoittaa merkkijonon string palauttaen allekirjoituksen joka on muotoa tuple.Parametriin K tulee syöttää satunnaisia merkkejä, joiden avulla allekirjoitus tehdään.

size()Palauttaa suurimman mahdollisen merkkijonon koon bitteinä, joka pystytään salaamaan taiallekirjoittamaan. Mikäli luku ei ole jaollinen kahdeksalla, on suurin mahdollinen kokomerkkeinä palautettu arvo jaettuna kahdeksalla pyöristettynä alaspäin

verify(string, signature)Palauttaa arvon True jos allekirjoitus signature vastaa annettua merkkijonoa string. Muutoinpalauttaa arvon False.

Lisäksi osalla salausalgoritmeista (Kuten ElGamal ja DSA) on omia lisätoimintoja, mutta niistävoit lukea tarkemmin alkuperäisestä manuaalista [2].

Page 18: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

17

Huomioita turvallisuudesta

Mikä tahansa näistä algoritmeista voidaan periaatteessa purkaa triviaalisti: Esimerkiksikäyttämämme RSA-algoritmi voidaan purkaa helposti kokeilemalla kaikki alkulukuparit välilläkahdesta n:ään. Nämä arvot voidaan löytää helposti seuraavanlaisella koodilla:

for i in range(2, n): if (n%i)==0: print i, 'is a factor' ; break

Kannattaa kuitenkin huomata, että n on tavallisesti muutamia satoja bittejä pitkä, joten ohjelma eiluultavimmin löydä ratkaisussa käytettäviä lukuja ennen kuin aurinko sammuu lopullisesti.Älykkäämmät algoritmit löytävät ratkaisuja hieman nopeammin, mutta siitäkään huolimattaratkaisuja ei löydetä järkevässä ajassa. Lisäksi ElGamal ja DSA käyttä diskreetteja logaritmejä,mutta niilläkin ajatus on sama.

Turvallinen avainkoko riippuu murtamisessa käytetystä laitteistosta. Nykyisellä laitekannallaalkulukupohjaisen algoritmin avaimille 512 bittiä riittää kotikäytössä sekä 768 yritysmaailmantarpeisiin. 1024-bittinen avain alkaa lähestyä sotilastiedustelutason salausavainta, ja on kotikäytössäjo tarpeettoman vahva. ElGamal- tai DSA-algoritmit ovat logaritmipohjaisia, joten niidenyhteydessä on suositeltavaa kertoa nämä avainkoot kahdella.

Page 19: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

18

Crypto.Util: Muita työkaluja

Alkuperäinen lähde Python Crypthography Toolkit Manual, http://www.amk.ca/python/writing/pycrypt/

Tässä luvussa käsittelemme niitä osia Python Cryptography Toolkitistä, jotka eivät sovi muihinkategorioihin.

Crypto.Util.number

Tämä moduulin osa sisältää työkaluja, joilla voidaan toteuttaa salauksessa tarvittavia matemaattisiafunktioita.

GCD(x,y)Palauttaa x:n ja y:n suurimman yhteisen nimittäjän.

getPrime(N, randfunc)Palauttaa N-bittisen satunnaisen alkuluvun käyttäen apunaan käyttäjän määrittelemääsatunnaislukugeneraattoria randfunc. Tällaisena satunnaislukugeneraattorina voidaankäyttää vaikkapa RandPool.get_bytes – generaattoria.

getRandomNumber(N, randfunc)Muuten sama kuin yllä, mutta palauttaa N-bittisen satunnaisluvun, joka ei välttämättä olealkuluku.

inverse(u, v)Palauttaa u:n jakojäännös v:stä –laskutoimituksen käänteisarvon.

isPrime(N)Palauttaa arvon True jos N on alkuluku. Testaus suoritetaan Rabin-Miller-testillä.

Crypto.Util.randpool

Kryptografian tarkoituksiin joudutaan usein tuottamaan erillisiä satunnaislukugeneraattoreita juurisiitä syystä, että normaalit satunnaislukugeneraattorit eivät ole riittävän satunnaisia. Tämä taasaiheuttaa tilanteen, jossa seuraamalla pitkällä aikavälillä satunnaislukugeneraattorin toimintaa,voidaan sen tuottamia lukuja alkaa arvaamaan, ja pitkäaikaisen kertymän avulla jopa tunnistaa,miten satunnaislukuja on tuotettu. Tämä on ongelmallista, koska mikäli pystymme tietämään mitälukuja tulevilla kierroksilla luultavasti esiintyy sekä miten generaattori toimii, voimme luoda tuleviaavaimia ennen niiden käyttöönottoa. Tätä vastaan voidaan kuitenkin toimia käyttämälläsatunnaislukuina salaus- tai tarkastuslukualgoritmin läpi ajettuja satunnaislukuja: tällöinsatunnaislukujen ennustaminen on yhtä vaikeaa kuin itse algoritmin murtaminen.

Käytettäessä satunnaislukugeneraattoreita tulisi entropian konsepti ymmärtää mahdollisimmanhyvin. Entropialla tarkoitetaan tässä tapauksessa satunnaisuuden määrää järjestelmässä, ja senmitääyksikkönä käytetään tavallisesti bittejä. Jos meillä on käytössämme yksi satunnainen bitti, on

Page 20: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

19

sen entropia silloin yhden bitin verran, vastaavasti yhden satunnaisen tavun entropia on 8 bittiä.Entäpä jos meillä on käytössä tietokannan kenttä, johon valitaan henkilön sukupuolen mukaan M taiN? Vaikka yhden merkin luontainen entropia on 8 bittiä, on meillä siitäkin huolimatta käytössämmeainoastaan kaksi valintaa, jolloin entropia pienenee yhteen bittiin.

Jos ajaisimme tälle yhden tavun kokoiselle kentälle tarkastusluvun joka ilmaistaan 128 bitillä,olisiko entropia silloin 128 bittiä? Ei tietenkään, koska kenttä voi tuottaa ainoastaan kaksi erilaistatarkastuslukua, joten sen entropia on edelleen yksi bitti. Jos yrittäisit rikkoa salausta, voisit tästäkohdasta päätellä kentän tarkastuslukua vastaavan arvon olevan joko M tai N. Koska kenttä eihyväksy muita vaihtoehtoja - kuten A, H tai K - ei sinun tarvitse myöskään kokeilla niitä. Tämäsääntö pätee myös luonnolliseen kieleen: esimerkiksi englanninkielisessä tekstissä kuuden merkinentropia on huomattavasti vähemmän kuin 6*8 eli 48 bittiä. Koska selkokielessä ei käytetä kaikkiakombinaatioita – kuten ”zD3yfx” tai ”KMH,DB”, on arvo huomattavasti vähemmän kuin kaikkienteoreettisten kombinaatioiden summa.

Kuinka tämä sitten liittyy satunnaislukugeneraattoreihin? Me haluamme järjestelmään riittävästientropiaa, että emme joudu alttiiksi hyökkäyksille. Esimerkiksi voisimme tehdä ohjelman, jokaarpoo käyttäjille mitään tarkoittamattomia salasanoja: idea olisi hyvä, koska järjestelmä estäisikäyttäjiä valitsemasta itsestään selviä salasanoja, kuten etunimiä, nimikirjaimia tailemmikkieläinten nimiä. Jos satunnaisgeneraattorimme kuitenkin toimisi siten, että se arpoisi 32alkuosan joukosta alun, 32 toisen osan joukosta keskiosan ja loppuun vielä numeron väliltä 0-32tyyliin ”mik-DAK-23” tai ”rip-ZOK-11”, saisimme varmaan turvallisen salasanan? Emme saisi,sillä oikeasti erilaisia salasanoja olisi ainoastaan 32*32*32 eli 32768 erilaista. Tämä määrä olisitäysin riittämätön suojaamaan järjestelmäämme ja käytännössä oikeilla työkaluilla triviaalistirikottavissa. Vielä 32-bittinen RSA-avain, jossa on noin 4.2 miljardia erilaista kombinaatiota, onriittämätön puhuttaessa vakavasta tietoturvauhasta.

Joka tapauksessa, randpool –moduuli toteuttaa tehokkaan satunnaislukugeneraattorinRandomPool-rakenteen avulla. Tämä satunnaislukugeneraattori pitää kirjaa generaattoristapoistuneesta entropiasta ja tasapainottaa sen määrää sisäisten funktioidensa avulla. Lisäksi kirjastoosaa myös kerätä aidosti satunnaista kohinaa mm. käyttäjän näppäinpainallusten tarkkaa aikaa japainettua nappia hyödyntämällä.

RandomPool([numbytes, cipher, hash])

RandomPool-objekti voidaan halutessa luoda kokonaan ilman parametreja edellisessäluvussa olleen esimerkin tavoin. Parametrilla numbytes voidaan säätääsatunnaislukugeneraattorin luomien lukujen määrää, ja parametrilla hash voidaan valitatarkastuslukufunktio, jolla satunnaislukujoukkoa “sekoitetaan”. Parametri cipher onpoistunut käytöstä version 1.1 jälkeen, mutta se on edelleen sisällytetty funktiokutsuun. Senvoi jättää tyhjäksi.

RandomPool –objekteilla on seuraavia muuttujia sekä metodeja:

addEvent(time[, string])Syöttää satunnaistietoa generaattorille. Parametriksi time kannattaa antaa senhetkinenkellonaika, parametriksi string satunnaista tekstiä tai merkkijonoja. Hyvä keino onesimerkiksi ohjata käytettyjä tarkastuslukuja tai satunnaisten muistiosoitteiden tietojageneraattoriin, koska nämä ovat tietoa jota ei yleisesti voida käyttää generaattorinmurtamiseen. Paluuarvona palautuu järjestelmän uusi entropia-arvo self.entropy.

Page 21: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

20

bitsInteger-arvo, joka kertoo kuinka monta tavua satunnaislukuja generaattori sisältää.Käytännössä arvo on bytes-arvo jaettuna kahdeksalla ja pyöristettynä alaspäin.

bytesInteger-arvo, joka kertoo kuinka monta bittiä satunnaisdataa generaattorissa on.

entropyInteger-arvo, joka kertoo kuinka paljon entropiaa satunnaislukugeneraattori sisältää.addEvent() kasvattaa arvoa, getBytes laskee sitä.

getBytes(num)Palauttaa merkkijonon jossa on num tavua satunnaista tietoa. Metodi ei aiheuta virhettä,vaikka satunnaisgeneraattorin entropia-arvo olisikin nolla tai pääsisi menemään nollaan.Tämä käytännössä vain tarkoittaisi sitä, että generaattorin luvut eivät enää ole täysinsatunnaisia. Riittävän entropian säilyttäminen jätetäänkin käyttäjän vastuulle.

stir()Sekoittaa satunnaislukulistaa käyttäen alustuksessa määrättyä tarkastuslukufunktiota. Onsuositeltavaa, että stir-metodia käytetään aina, kun generaattoriin lisätään lukujaaddEvent()-metodilla tai kun sieltä otetaan lukuja getBytes-metodilla.

PersistentRandomPool-rakenne on alirakenne RandomPool:ille, joka mahdollistaa generaattorinsisällön lataamisen ja tallentamisen levyltä sekä kyvyn luoda satunnaisdataanäppäimistöpainalluksista. Rakenteella on muuten samat ominaisuudet, mutta seuraavissatoiminnoissa on eroavaisuuksia:

PersistentRandomPool([filename, numbytes, cipher, hash])Käytännössä sama kuin RandomPool, mutta ottaa lisäksi tiedostonnimen, josta generaattorinsisältö luetaan. Jos tiedostoa ei ole olemassa, sellainen luodaan ja generaattori alustetaannormaalisti. Jos tiedostonnimeä ei anneta, toimii rakenne kuten RandomPool-rakenne.

randomize()(Unix -järjestelmäkohtainen) Ottaa satunnaistietoa käyttäjältä. Pyytää käyttäjää painamaannäppäimistön satunnaisia kirjaimia, joista muodostaa aidosti satunnaista tietoageneraattorille.

save()Tallentaa generaattorin sisällön alustuksessa määriteltyyn tiedostoon.

Page 22: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

21

Loppusanat

Tässä on tällä erää kaikki, mitä Python Cryptography Toolkitin käyttöopas piti sisällään. Mikälikiinnostuit salaustekniikoista tai niiden hyödyntämisestä omien ohjelmiesi parissa, kannattaa sinuntutustua PCT:n kotisivuilta [2] saatavilla oleviin esimerkkikoodeihin, joissa teknisesti pidemmällemenneiden esimerkkien avulla opetetaan käytännössä työkalun käyttöä.

Tavallisesti salausalgoritmeja käytetään pääasiassa tietoliikennetekniikassa, joten et vielä tässävaiheessa saanut oppaasta muuta irti kuin että pääsit alkuun erilaisten salausavainten kanssa. Kunjatkossa tutustut tietoliikenneohjelmointiin ja viestinvaihtoon, olet jo valmiiksi opetellut käyttämääntietoliikenteen salauksessa tarvittavia asioita. Lisäksi voit tietenkin soveltaa oppaan ohjeita, ja salatatyöasemaltasi tietoja, joiden et halua päätyvän muiden nähtäville.

Kuitenkin kannattaa muistaa, että tärkein lähtökohta tietoturvassa ei ole mahdollisimman vahvansalausalgoritmin käyttäminen, vaan nimenomaan salasanan valinta: paraskaan algoritmi ei autasinua, jos salasanasi on heikko tai itsestään selvä. Älä käytä omaa nimeäsi, nimikirjaimiasi,syntymäaikaasi, puolison nimeä tai lemmikkien kutsumanimiä salasanoina. Hyvässä salasanassa onaina sekaisin isoja ja pieniä kirjaimia sekä numeroita eikä se tarkoita mitään. On tietenkinymmärrettävää, että tällaisen salasanan muistaminen on vaikeaa. Älä kuitenkaan kirjoita salasanaalapulle ja jätä sitä mihinkään itsestään selvään paikkaan, kuten näppäimistön tai työtason alle taiavoimeen työpöydän laatikkoon. Jos ehdottomasti haluat kirjoittaa salasanan ylös, niin säilytälappua edes lukitussa laatikossa, johon ainoastaan sinulla on avain, tai talleta se kännykkääsi SIM-kortille viesteihin tai kontaktitietoihin ilman muita lisätietoja: luultavasti et anna sellaisten tahojenselata kännykkääsi joiden et myöskään haluaisi käyttävän tietokonettasi. Ja mikäli kännykkäsihäviää, lukittuu salasana SIM-kortin sisään kun kuoletat liittymäsi. Äläkä tietenkään kerrokenellekään, että olet tallentanut työaseman salasanasi kännykäsi viesteihin.

Useimmiten tietoturva onkin juuri tämänkaltaisia pieniä asioita. Vahvimmatkin salaukset voidaanohittaa luottamalla käyttäjien virheisiin, joten huolehdi että et vahingossa itse aiheuta suurintatietoturvariskiä omalle työasemallesi. Siihen ei auta edes ElGamal-suojauksella allekirjoitettu MD5-tarkastussumma.

Page 23: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

22

Lähteet

[1] Kasurinen, Jussi (2006) Python-ohjelmointiopas., versio 1. Tietotekniikan käsikirjat 7,Lappeenrannan teknillinen yliopisto.

[2] Kuchling, A.M. (2007) Python Cryptography Toolkit Manual. Viitattu 12.6.2007. Saatavillaosoitteesta http://www.amk.ca/python/writing/pycrypt/

[3] Kasurinen, Jussi (2007) Python –grafiikkaohjelmointi Imaging Librarylla. Tietotekniikankäsikirjat 8, Lappeenrannan teknillinen yliopisto.

[4] Kuchling, A.M. (2006), Python Enhancement Proposal 247: API for Cryptographic HashFunctions. Saatavilla osoitteesta http://www.python.org/dev/peps/pep-0247/, viitattu 28.6.2007.

[5] Kuchling, A.M. (2006), Python Enhancement Proposal 272: API for Block EncryptionAlgorithms. Saatavilla osoitteesta http://www.python.org/dev/peps/pep-0272/, viitattu 28.6.2007.

Page 24: PYTHON KRYPTAUSOPAS - it.lut.fi · Python – kryptausopas LTY 5 Hash-funktio Luvun pituus MD2 128 bittiä MD4 128 bittiä MD5 128 bittiä RIPEMD 160 bittiä SHA 160 bittiä Kaikilla

Python – kryptausopasLTY

23

Lisenssiehdot

Kannen kuva: Nila Gurusinghe. Kuva julkaistu Creative Commons - Nimi mainittava 2.0 -lisenssillä.

Tähän asiakirjaan sovelletaan Creative Commonsin “Vapaa Yleinen Käyttö” (Public Domain) –lisenssiä.

Esimerkit ja muut tehtävät on suunniteltu siten, että niiden käytöstä ei pitäisi koitua ongelmia, muttasiitäkin huolimatta lopullinen vastuu tehtävien ajamisesta jätetään lukijalle. Oppaan tekemiseenosallistuneet henkilöt tai LTY eivät vastaa mahdollisista ongelmista, vahingoista, vioista, tappioistatai tuotannonmenetyksistä.

Lappeenrannan teknillinen yliopisto 2007