Prošlogodišnja lekcija o bezbjednosti i privatnosti se fokusirala na to kako možete biti bezbjedniji kao korisnik računara. Ove godine, fokusiraćemo se na bezbjednost i koncepte kriptografije koji su relevantni u razumijevanju alata koji su pokriveni u ranijim lekcijama, kao što su hash funkcije u Git-u, ili funkcija za izvoženje ključeva i simetrični/asimetrični kriptosistemi u SSH.
Ova lekcija nije zamjena za rigoroznije i kompletnije kurseve zaštite računarskih sistema (6858) ili kriptografije (6857 i 6875). Nemojte se baviti bezbjednosnim poslom bez formalne obuke o bezbjednosti. Osim ako ste ekspert, nemojte roll your own crypto. Isti principi važe za bezbjednost sistema.
Ova lekcija ima veoma informativnu (ali mi razmišljamo praktično) primjenu osnovnih kriptografskih koncepata. Ova lekcija neće biti dovoljna da bi vas naučila dizajn bezbjednosnih sistema ili kriptografskih protokola, ali se nadamo da će biti dovoljna da vam pruži opšte razumijevanje programa i protokola koje vi već koristite.
Entropija
Entropija je mjera slučajnosti. Ovo je korisno, na primer, kada određujete jačinu lozinke.
Kao što XKCD comic iznad ilustruje, lozinke kao što su "correcthorsebatterystaple" je sigurnija u odnosu na "Tr0ub4dor&3". Ali kako mjerite nešto ovog tipa?
Entropija se mjeri u bitovima, i kada izaberete jednoobrazan slučajan odabir iz niza mogućih rezultata, entropija je jednaka
1
log_2(# of possibilities)
Trebali bi da uzmete u obzir da napadač zna model lozinke, ali ne i slučajnosti (npr. iz dice rolls koje se koriste da bi se selektovala posebna lozinka.
Koliko bitova entropije je dovoljno? Zavisi od vašeg modela prijetnje. Za online nagađanje, kao što XKCD comic iznosi, ~40 bitova entropije je prilično. Da bi bili otporni na offline nagađanje, jača lozinka će biti neophodna (npr. 80 bitova, ili više).
Hash funkcije
Kriptografske hash funkcije mapiraju podatke proizvoljne veličine u fiksnu veličinu, i imaju neka specijalna svojstva. Slijedi gruba specifikacija hash funkcije:
1
hash(value: array<byte>) -> vector<byte, N> (for some fixed N)
Primjer hash funkcije je SHA1, koji se koristi u Git-u. Mapira proizvoljnu veličinu inputa na 160-bit outputa (što može biti predstavljeno kao 40 heksadecimalnih karaktera). Možemo isprobati SHA1 hash na inputu koristeći
1
sha1sum
1 2 3 4 5 6
$ printf 'hello' | sha1sum aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d $ printf 'hello' | sha1sum aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d $ printf 'Hello' | sha1sum f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0
Na visokom nivou, hash funkcija se može posmatrati kao teško inverzivna slučajnog izgleda (ali deterministička) funkcija (i ovo je idealni model hash funkcije). Hash funkcija ima sledeća svojstva:
- Determinizam - isti input uvijek generiše isti output.
- Ne-inverzivnost - teško je pronaći input kao što je
1
m
za neki željeni output1
hash(m) = h
.1
h
- Ciljano otporna na udar - ukoliko je dat input , teško je pronaći drugačiji input
1
m_1
tako da je1
m_2
.1
hash(m_1) = hash(m_2)
- Otporna na sudar - teško je pronaći dva inputa i
1
m_1
tako da je1
m_2
(imajte u vidu da je ovo mnogo jače svojstvo u odnosu na ciljani otpor na udar)1
hash(m_1) = hash(m_2)
Napomena: Iako može funkcionisati za određene svrhe, SHA-1 se više ne smatra jakom kriptografskom hash funkcijom. Tabela životnog vijeka hash funkcija vam može biti interesantna. Ipak, imajte u vidu preporuku da su preporučene specifične hash funkcije izvan opsega ove lekcije. Ukoliko se bavite poslom gdje je ovo bitno, potrebna vam je formalna obuka u bezbjednosti/kriptografiji.
Aplikacije
- Git, za sadržajno-adresirano skladište. Ideja hash funkcije je više opšti koncept (postoje ne-kriptografske hash funkcije). Zašto Git koristi kriptografsku hash funkciju?
- Kratak rezime sadržaja datoteke. Softver može često biti preuzet iz (potencijalno manje pouzdanih) mirrors, npr. Linux ISO's, i bilo bi lijepo da im ne moramo vjerovati. Zvanični sajtovi obično postavljaju hashove zajedno sa linkom za preuzimanjem (to upućuje na mirror treće strane), tako da hash može biti provjeren nakon preuzimanja fajla.
- Commitment schemes. Pretpostavimo da želite da commitujete određenoj vrijednosti, ali da otkrijete samu vrijednost kasnije. Na primer, ukoliko želim "u svojoj glavi" da uradim fer bacanje novčića bez provjerenog zajedničkog novčića koji dvije strane mogu da vide. Mogao bih da izaberem vrijednost , i onda da podijelim
1
r=random()
. Zatim, mogli bi da izaberete glavu ili pismo (čak smo se i usaglasili da parno1
h = sha256(r)
znači glava, i neparno1
r
znači pismo). Nakon vašeg izbora, mogao bih da otkrijem moju vrijednost1
r
, a vi bi mogli da potvrdite da nisam varao provjeravajući da li se1
r
poklapa sa hashom koji sam ranije podijelio.1
sha256(r)
Derivacione funkcije ključa
Povezani koncept sa kriptografskim hash-evima, derivacione funkcije ključa (KDFs) se koriste za više aplikacija, uključujući stvaranje outputa fiksne dužine da bi se koristili kao ključevi u drugim kriptografskim algoritmima. Obično, KDF su namjerno spori, u cilju usporavanja offline napada brutalnom silom.
Aplikacije
- Stvaranje ključeva iz fraza da bi se koristili u drugim kriptografskim algoritmima (npr. simetrična kriptografija, pogledajte ispod).
- Čuvanje login kredencijala. Čuvanje lozinki u čistom tekstu je loše: pravi pristup je generisanje i čuvanje random salt za svakog korisnika, čuvanje
1
salt = random()
, i verifikovanje pokušaja prijave ponovnim izračunavanjem KDF-a s obzirom na unešenu lozinku i uskadišteni salt.1
KDF(password + salt)
Simetrična kriptografija
Skrivanje sadržaja poruke je vjerovatno prvi koncept koji vam padne na pamet kada razmišljate o kriptografiji. Simetrična kriptografija ovo izvršava sa sledećim setom funkcionalnosti:
1 2 3 4
keygen() -> key (this function is randomized) encrypt(plaintext: array<byte>, key) -> array<byte> (the ciphertext) decrypt(ciphertext: array<byte>, key) -> array<byte> (the plaintext)
Šifrovana funkcija ima svojstvo koje je dao output (ciphertext), teško je utvrditi input (plaintext) bez ključa. Dekriptovana funkcija ima očigledna svojstva za ispravljanje, tako da je
1
decrypt(encrypt(m, k), k) = m
Primjer simetričnih kriptosistema koji se široko koristi danas je AES.
Aplikacije
- Enkriptovani fajlovi za skladištenje u cloud servisu kojem ne vjerujete. Ovo može biti u kombinaciji sa KDF-om, tako da možete enkriptovati fajl sa frazom. Generišite , a zatim čuvajte
1
key = KDF(passphrase
.1
encrypt(file, key)
Asimetrična kriptografija
Termin "asimetrična" odnosi se na postojanje dva ključa, sa dvije različite uloge. Privatni ključ, kao što mu samo ime kaže, znači da je napravljen da bi bio privatan, dok se javni ključ može javno dijeliti i to neće uticati na bezbjednost (za razliku od dijeljenja ključa u simetričnim kriptosistemima). Asimetrični kriptosistemi pružaju sledeći set funkcionalnosti, da enkriptuju/dekriptuju i da potpišu/ovjere:
1 2 3 4 5 6 7
keygen() -> (public key, private key) (this function is randomized) encrypt(plaintext: array<byte>, public key) -> array<byte> (the ciphertext) decrypt(ciphertext: array<byte>, private key) -> array<byte> (the plaintext) sign(message: array<byte>, private key) -> array<byte> (the signature) verify(message: array<byte>, signature: array<byte>, public key) -> bool (whether or not the signature is valid)
Encrypt/decrypt funkcije imaju svojstva koja su slična njihovim analozima iz simetričnih kriptosistema. Poruka može biti enkriptovana koristeći public ključ. Uzimajući u obzir output (ciphertext), teško je odrediti input (plaintext) bez privatnog ključa. Decrypt funkcija ima očigledna svojstva ispravljanja, tako da je
1
decrypt(encrypt(m, public key), private key) = m
Simetrična i asimetrična enkripcija se mogu uporediti sa fizičkim zaključavanjem. Simetrični kriptosistem je kao zaključavanje vrata: svako sa ključem može da ih zaključa i otključa. Asimetrična enkripcija je kao katanac sa ključem. Mogli biste nekome dati otključanu bravu (javni ključ), oni bi mogli ostaviti poruku u kutiji i zatim zaključati, i nakon toga, samo vi biste mogli da otvorite bravu jer samo vi imate ključ (privatni ključ).
Sign/Verify funkcije imaju ista svojstva za koja bi se nadali da ih fizički potpisi imaju, sa njima je teško falsifikovati potpis. Bez obzira na poruku, bez privatnog ključa, teško je stvoriti takav potpis pa da
1
verify(message, signature, public key)
1
verify(message, sign(message, private key), public key) = true
Aplikacije
- PGP email enkripcija. Ljudi mogu njihove javne ključeve objaviti online (npr. na PGP keyserver, ili na Keybase). Bilo ko im može poslati enkriptovani mejl.
- Privatno dopisivanje. Aplikacije kao Signal i Keybase koriste asimetrične ključeve da omoguće privatne komunikacione kanale.
- Signing softver. Git može imati GPG-signed commits i tagove. Sa objavljenim javnim ključem, svako može potvrditi autentičnost preuzetog softvera.
Distribucija ključeva
Asimetrična kriptografija ključeva je odlična, ali ima veliki izazov kada je u pitanju distribucija javnih ključeva / mapiranja javnih ključeva identitetima u stvarnom svijetu. Postoji mnogo rešenja za ovaj problem. Signal ima jedno jednostavno rešenje: povjerenje pri prvoj upotrebi, i podrška out-of-band razmjene javnih ključeva (provjeravate "sigurne brojeve" vaših prijatelja uživo). PGP ima različito rešenje, a to je web of trust. Keybase ima još jedno rešenje social proof (zajedno sa ostalim dobrim idejama). Svaki model ima svoje prednosti: mi (instruktori) volimo Keybase model.
Studije slučaja
Menadzeri lozinke
Ovo je suštinski alat koji bi svako trebao da pokuša da koristi (npr. KeePassXC). Mendzeri lozinki vam dopuštaju da koristite jedinstvenu, slučajno generisanu lozinku visoke entropije za sve vaše sajtove, i oni čuvaju sve vaše lozinke na jednom mjestu, enkriptovani sa simetričnom šifrom i ključem dobijenim od fraze koristeći KDF.
Korišćenje menadzera lozinke utiče na izbjegavanje ponovnog korišćenja lozinke (tako da ste manje oštećeni kada sajt postane ugrožen), koriste se lozinke sa velikom entropijom (tako da su vam manje šanse da postanete ugroženi), i samo je potrebno zapamtiti jednu lozinku sa visokom entropijom.
Dvofaktorna autentikacija
two-factor authentication (2FA) zahtjeva od vas da koristite frazu ("nešto što vi znate") zajedno sa 2FA autentikatorom (kao što je YubiKey, "nešto što imate") da bi vas zaštitila od krađe lozinki i phishing napada.
Enkripcija čitavog diska
Enkripcija čitavog diska vašeg laptop-a je lak način da zaštitite vaše podatke u slučaju da je vaš laptop ukraden. Možete koristiti cryptsetup + LUKS na Linuxu, BitLocker na Windowsu, ili [FireVault] na macOS. Ovo će enkriptovati čitav disk sa simetričnim cipher-om, i sa ključem koji je zaštićen frazom.
Privatne poruke
Koristite Signal ili Keybase. End-to-End bezbjednost je pokrenuta od asimetrične enkripcije ključa. Ovdje je pribavljanje javnog ključa vaših kontakata kritičan korak. Ukoliko želite dobru bezbjednost, morate da autentikujete javne ključeve out-of-band(Sa Signalom ili Keybase-om), ili da vjerujete društvenim dokazima (sa Keybase-om).
SSH
Pokrili smo upotrebu SSH i SSH ključeva u ranijoj lekciji. Hajde da pogledamo kriptografske aspekte ovoga.
Kada pokrenete
1
ssh-keygen
1
public_key
1
private_key
1
ssh-keygen
U praksi, jednom kada server sazna javni ključ klijenta (sačuvan u
1
.ssh/authorized_keys
1
.ssh/authorized_keys
Resursi
- Zabilješke od prošle godine: kada je ova lekcija bila više fokusirana na bezbjednost i privatnost korisnika računara
- Pravi odgovori vezani za kriptografiju: odgovori "koji crypto bih trebao da koristim za x?" za mnoge česte x.
Vježbe
- Entropija
- Pretpostavimo da je lozinka izabrana kao spajanje četiri riječi sa malim slovima iz rječnika, gdje je svaka riječ izabrana jednako nasumično iz rečnika od veličine od 100.000. Primjer takve lozinke je . Koliko bitova entropije on ima?
1
correcthorsebatterystaple
- Uzmite u obzir alternativnu šemu gdje je lozinka izabrana kao dio od 8 random alfanumeričkih karaktera (uključujući karaktere i sa malim i sa velikim slovom). Jedan primjer je . Koliko on ima bitova entropije?
1
rg8Ql34g
- Koja je lozinka jača?
- Pretpostavimo da napadač pokušava da pogodi 10.000 lozinki po sekundi. Prosječno, koliko će mu vremena trebati da probije svaku od lozinki?
- Pretpostavimo da je lozinka izabrana kao spajanje četiri riječi sa malim slovima iz rječnika, gdje je svaka riječ izabrana jednako nasumično iz rečnika od veličine od 100.000. Primjer takve lozinke je
- Kriptografkse hash funkcije. Preuzmite Debian sliku iz mirror (npr. iz ovog Argentinean mirror). Unaprijed provjerite hash (npr. koristeći komandu) sa hashom preuzetim sa zvanične Debian stranice (npr. ovaj fajl je hostovan na
1
sha256sum
, ukoliko ste preuzeli link fajl sa Argentinean mirror).1
debian.org
- Simetrična kriptografija. Enrkiptujte fajl sa AES enkripcijom, koristeći OpenSSL: . Pogledajte sadržaje koristeći
1
openssl aes-256-cbc -salt -in {input filename} -out {output filename}
i1
cat
. Dekriptujte ga sa1
hexdump
i potvrdite da se sadržaj poklapa sa originalom koristeći1
openssl aes-256-cbc -d -in {input filename} -out {output filename}
.1
cmp
- Asimetrična kriptografija.
- Postavite SSH keys na računar kojem imate pristup (ne Athena, jer Kerberos ima čudnu interakciju sa SSH ključevima). Umjesto da koristite RSA ključeve kao u linkovanom tutorijalu, koristite sigurnije ED25519 keys. Provjerite da li je vaš privatni ključ enkriptovan sa frazom, tako da je zaštićen.
- Postavite GPG
- Pošaljite Anishu enkriptovani mejl (javni ključ).
- Potpišite Git commit sa ili kreirajte potpisani Git tag sa
1
git commit -S
. Ovjerite potpis commita sa1
git tag -s
ili sa tagom koristeći1
git show --show-signature
.1
git tag -v