Simetrična Kriptografija
Simetrična kriptografija podrazumeva sistem za šifrovanje koji koristi isti ključ i za šifrovanje i za dešifrovanje. To je najstariji i najbrži oblik kriptografije, koji se koristi svuda gde je potrebna efikasna zaštita podataka — od komunikacije do skladištenja.
Postoje dve glavne vrste šifarskih sistema:
- Protočni (stream ciphers)
- Blokovski (block ciphers)
Protočni sistemi (Stream Ciphers)
Protočni sistemi rade tako što generišu beskonačan niz pseudo-nasumičnih bitova (keystream) koji se kombinuje sa porukom, obično XOR operacijom. Ključna ideja je da od kratkog tajnog ključa napravimo dugačak niz koji izgleda nasumično.
Kako funkcioniše
Najjednostavniji pristup je da pošiljalac i primalac unapred dogovore ključ iste dužine kao i poruka (one-time pad). Ovo je teoretski savršeno sigurno, ali ima ozbiljnih praktičnih mana:
- Ključ mora biti jednako dugačak kao poruka
- Ključ se sme koristiti samo jednom — otud naziv
- Razmena tako dugačkog ključa je komplikovana
Zbog toga se u praksi koriste pseudo-nasumični generatori (PRNG) koji od kratkog ključa generišu dugačak keystream.
Zašto je opasno ponavljati isti ključ
Ako se isti ključ $k$ upotrebi za šifrovanje dve različite poruke $m_1$ i $m_2$:
$$ c_1 = m_1 \oplus k, \quad c_2 = m_2 \oplus k $$
Napadač koji zna $c_1$ i $c_2$ može da izračuna:
$$c_1 \oplus c_2 = m_1 \oplus m_2$$
Ovo u potpunosti eliminiše tajnost ključa i napadaču daje direktan uvid u odnos dveju poruka — a iz poznatog dela teksta može se rekonstruisati ostatak.
Šta čini dobar generator pseudo-nasumičnih bitova
Generatori koji se koriste u kriptografiji moraju zadovoljiti stroge zahteve:
- Veliki period — niz se ne sme ponoviti prebrzo
- Statističke osobine — mora proći standardizovane testove nasumičnosti (npr. NIST SP 800-22 test suite)
- Velika linearna složenost — nije ga lako aproksimirati linearnom povratnom smenom (LFSR)
- Nepredvidivost — čak i uz poznavanje prvih milijardu generisanih bitova, verovatnoća pogađanja sledećeg bita ne sme biti veća od 50%
Ovi uslovi su neophodni, ali ne i dovoljni za kriptografsku sigurnost.
Poznati primeri
| Algoritam | Status |
|---|---|
| RC4 | Probijen, ne koristi se |
| A5/1 | Teorijski probijen, ali još u upotrebi (GSM) |
| ChaCha20 | Moderan, siguran, široko korišćen |
Blokovski sistemi (Block Ciphers)
Blokovski sistemi šifruju poruku u fiksnim blokovima određene veličine. Za razliku od protočnih, svaki blok otvorenog teksta se preslikava u blok šifrata koristeći isti ključ — ali uvek ceo blok odjednom.
Padding
Poruke nisu uvek umnozak dužine bloka, pa se koristi padding — dopunjavanje poruke do željene dužine.
PKCS#7 padding: Ako treba dodati n bajtova, svaki od tih bajtova ima vrednost $n$.
Na primer, ako je blok 16 bajtova i poruka je duga 11 bajtova, dodaje se 5 bajtova sa vrednošću 0x05:
Poseban slučaj: ako je poruka već tačne dužine, dodaje se ceo dodatni blok gde svi bajtovi imaju vrednost jednaku dužini bloka. Ovo omogućava jednoznačno uklanjanje paddinga pri dešifrovanju.
DES (Data Encryption Standard)
DES je bio prvi standardizovani algoritam za simetrično šifrovanje, usvojen 1977. godine. Koristi blokove od 64 bita i ključ od 56 bita, što je danas nedovoljno — iscrpna pretraga prostora ključeva je izvodljiva na modernom hardveru.
Trostruki DES (3DES): Pokušaj produžavanja veka DES-a primenom algoritma tri puta. Može se koristiti sa dva ili tri ključa. Zanimljivo je da verzija sa tri ključa nije drastično sigurnija od verzije sa dva ključa, ali zahteva razmenu više podataka.
Meet-in-the-Middle napad: Dvostruki DES (2DES) se naivno čini dvostruko sigurnijim, ali MITM napad pokazuje da efektivna sigurnost raste samo linearno, ne eksponencijalno.
DES se danas smatra zastarelim i ne koristi se u novim sistemima.
AES (Advanced Encryption Standard)
AES je trenutni standard za simetričnu blokovsku enkripciju, usvojen 2001. godine. Algoritam je razvio belgijski kriptografski tim (Rijndael) i odabran je nakon otvorenog međunarodnog takmičenja.
Parametri:
| Veličina ključa | Broj rundi |
|---|---|
| 128 bita | 10 |
| 192 bita | 12 |
| 256 bita | 14 |
AES uvek šifruje blokove od 128 bita bez obzira na dužinu ključa. Svaka runda se sastoji od četiri operacije: SubBytes, ShiftRows, MixColumns i AddRoundKey. Poslednja runda izostavlja MixColumns.
Korišćenje sa OpenSSL:
# Šifrovanje
openssl enc -aes-256-cbc -in plaintext.txt -out encrypted.bin
# Dešifrovanje
openssl enc -d -aes-256-cbc -in encrypted.bin -out plaintext.txt
Modovi za blokovske šifre
Sama blokovska šifra šifruje samo jedan blok. Da bi se šifrovala poruka proizvoljne dužine, koriste se modovi rada koji definišu kako se blokovi međusobno povezuju.
Ilustracija problema sa modovimaECB — Electronic Codebook
Najjednostavniji mod: svaki blok se šifruje nezavisno.
$$ c_i = E_k(m_i) $$
$$ m_i = D_k(c_i) $$
Prednosti: - Najjednostavnija implementacija - Moguća paralelizacija i šifrovanja i dešifrovanja - Greška u jednom bloku ne utiče na ostale
Mana Isti blok otvorenog teksta uvek daje isti blok šifrata. Ovo znači da se obrasci iz originalne poruke prenose u šifrat. Klasičan primer je slika (npr. Linux Tux penguin) gde se šifrovanom ECB metodom jasno vidi originalna kontura.
def encrypt(key: bytes, message: bytes) -> bytes:
blocks = bytes_to_blocks(message)
ciphertext = bytes()
for block in blocks:
ciphertext += encrypt_block(key, block)
return ciphertext
def decrypt(key: bytes, ciphertext: bytes) -> bytes:
blocks = bytes_to_blocks(ciphertext)
message = bytes()
for block in blocks:
message += decrypt_block(key, block)
return message
CBC — Cipher Block Chaining
CBC rešava problem ECB moda tako što svaki blok otvorenog teksta XORuje sa prethodnim blokom šifrata pre enkripcije. Na početku se koristi inicijalizacioni vektor (IV) koji zamenjuje nepostojeći "prethodni blok".
$$c_i = E_k(m_i \oplus c_{i-1}), \quad c_0 = IV$$
$$m_i = D_k(c_i) \oplus c_{i-1}$$
Karakteristike:
- Šifrovanje mora biti sekvencijalno (svaki blok zavisi od prethodnog)
- Dešifrovanje može biti paralelno (sve vrednosti $c_i$ su poznate unapred)
- IV ne mora biti tajan, ali ne sme se ponavljati sa istim ključem
- Greška u jednom bloku šifrata utiče samo na taj i sledeći blok pri dešifrovanju
Mana: Nije pogodan za slučajni pristup podacima (npr. pisanje na disk) — da bi se izmenio jedan blok, moraju se preračunati svi naredni.
def encrypt(key: bytes, message: bytes, iv: bytes) -> bytes:
blocks = bytes_to_blocks(message)
cipher = [iv]
for block in blocks:
cipher.append(encrypt_block(key, xor(block, cipher[-1])))
return blocks_to_bytes(cipher)
def decrypt(key: bytes, ciphertext: bytes) -> bytes:
blocks = bytes_to_blocks(ciphertext)
message = bytes()
for i in range(1, len(blocks)):
message += xor(decrypt_block(key, blocks[i]), blocks[i-1])
return message
CTR — Counter Mode
CTR mod pretvara blokovsku šifru u protočnu, eliminiišući potrebu za dešifrujućom funkcijom $D_k$.
Umesto direktnog šifrovanja poruke, šifruje se niz vrednosti nonce + brojač, a dobijeni keystream se XORuje sa porukom:
$$c_i = m_i \oplus E_k(\text{nonce} | i)$$
Prednosti:
- I šifrovanje i dešifrovanje su identični (samo XOR sa keystreamom)
- Moguca paralelizacija u oba smera
- Pogodan za slučajni pristup — može se šifrovati/dešifrovati samo jedan blok bez ostalih
Mane:
- Ako se isti nonce upotrebi dva puta sa istim ključem, dobijamo isti keystream — problem identičan one-time pad ponovnoj upotrebi
- Nema zaštite integriteta — napadač može da menja bitove u šifratu, a to će se direktno odraziti na otvoreni tekst bez detekcije
def encrypt(key: bytes, message: bytes, n: int) -> bytes:
keystream = bytes()
for i in range(0, 1 + len(message) // block_size):
keystream += encrypt_block(key, int.to_bytes(n + i, block_size))
return xor(message, keystream)
# Dešifrovanje je identično šifrovanju
decrypt = encrypt
GCM — Galois/Counter Mode - idejno
GCM je trenutno jedan od najpopularnijih modova i preporučuje se za većinu modernih primena. Kombinuje CTR šifrovanje sa Galois Message Authentication Code (GMAC) za autentifikaciju.
Šta GCM pruža:
- Poverljivost (confidentiality) — poruka je šifrovana CTR modom
- Integritet (integrity) — autentifikacioni tag detektuje svaku izmenu šifrata
- Autentičnost (authenticity) — potvrđuje da je poruku generisao neko ko zna tajni ključ
- Podrška za Associated Data (AAD) — podaci koji se autentifikuju, ali ne šifruju (npr. zaglavlja paketa)
Izlaz GCM-a su dva dela: šifrat i auth tag (obično 128 bita). Ako napadač promeni bilo koji bit šifrata, autentifikacija će otkriti izmenu.
GCM je osnova TLS 1.3 i modernih HTTPS veza.
Poređenje modova
| Mod | Paralelno šifrovanje | Paralelno dešifrovanje | Zaštita integriteta | Tipična primena |
|---|---|---|---|---|
| ECB | ✅ | ✅ | ❌ | Nikad u praksi |
| CBC | ❌ | ✅ | ❌ | TLS (starije verzije) |
| CTR | ✅ | ✅ | ❌ | Brza enkripcija |
| GCM | ✅ | ✅ | ✅ | TLS 1.3, HTTPS |
Gde se sve koriste simetrični kriptografski sistemi
Simetrična kriptografija je temelj gotovo svake digitalne komunikacije i zaštite podataka:
- Mrežna komunikacija — HTTPS (TLS), VPN, SSH, WPA2/WPA3 (WiFi), Bluetooth
- Šifrovanje diska — BitLocker, FileVault, dm-crypt (Linux), šifrovanje SSD-ova
- Aplikacije — menadžeri lozinki, end-to-end enkriptovani mesindžeri (Signal, WhatsApp)
- Generisanje pseudo-nasumičnih bitova — kriptografski PRNG-ovi koji se oslanjaju na AES
- Autentifikacioni kodovi — HMAC, CMAC (kombinacija heš funkcija i blokovskih šifri)
U praksi, simetrična kriptografija se gotovo uvek kombinuje sa asimetričnom: asimetrična kriptografija se koristi za bezbednu razmenu simetričnog ključa, a simetrična za brzu enkripciju podataka (jer je reda veličine hiljadu puta brža od asimetrične).