Section author: Domagoj Margan, Vedran Miletić

Korištenje osnovnih kriptografskih algoritama

Skup alata OpenSSL

OpenSSL je skup alata za baratanje protokolima Transport Layer Security (TLS) i Secure Sockets Layer (SSL). Koristi se za kodiranje i dekodiranje teksta, šifriranje datoteka, hashiranje, kriptografiju s javnim ključem, digitalno potpisivanje, stvaranje i povlačenje certifikata, testiranje TLS/SSL veza te brojne druge kriptografske funkcije. Slobodni je softver otvorenog koda inicijalno izdan pod vlastitom licencom sličnom Apachevoj, a verzije od 3.0.0 nadalje izdane su upravo pod licencom Apache 2.0. Podržava velik broj operacijskih sustava: primarna platforma koju autori koriste je Linux, ali podržani su i drugi operacijski sustavi slični Unixu (uključujući FreeBSD, OpenBSD, NetBSD, DragonFly BSD, macOS, Solaris i QNX) te OpenVMS i Microsoft Windows. Krajem 2018. godine OpenSSL je proslavio dvadeset godina postojanja.

OpenSSL ima četiri komponente koje implementiraju pojedine značajke: aplikacije, TLS, kriptografija i pogoni; svaka od njih je dodatno podijeljena u module. OpenSSL se može koristiti i kao aplikacija naredbenog retka i kao biblioteka, putem aplikacijskog programskog sučelja. Pored toga, moguće je i programirati vlastite pogone koji služe za korištenje akceleratora kriptografskih algoritama, bili ti akceleratori specifični za kriptografiju ili općeniti grafički procesori koji između ostalog mogu izvoditi i kriptografiju.

../../../../_images/openssl-conceptual-component.png

Konceptualne komponente OpenSSL-a. (Slika preuzeta iz OpenSSL Strategic Architecture.)

Kriptografski algoritmi

OpenSSL ima podršku za mnogo kriptografskih algoritama, koje možemo podijeliti u tri skupine:

Na službenim stranicama može se naći popis RFC-a koji je relevantan za implementacije tih algoritama u OpenSSL-u.

Biblioteke

OpenSSL je na većini distribucija Linuxa i drugih operacijskih sustava sličnih Unixu pakiran u tri dijela: biblioteka s kriptografskim algoritmima (libcrypto), biblioteka s implementacijom protokola TLS/SSL (libssl) i aplikacija naredbenog retka (openssl). Biblioteke libcrypto i libssl vrlo se često nalaze među osnovnim paketima distribucija Linuxa obzirom da ih brojne aplikacije koriste. Ilustracije radi, evo nekoliko primjera aplikacija koje koriste OpenSSL:

../../../../_images/openssl-packaging.png

Pakiranje OpenSSL-a. (Slika preuzeta iz OpenSSL Strategic Architecture.)

Aplikacija naredbenog retka

Aplikaciju naredbenog retka pokrećemo upisivanjem naredbe openssl uz odgovarajuće parametre i argumente. Kako bi provjerili koja je verzija OpenSSL-a instaliranja na sustavu, koristimo opciju version:

$ openssl version
OpenSSL 1.1.1a FIPS  20 Nov 2018

Warning

Za verziju koju imamo svakako treba provjeriti popis poznatih ranjivosti. Poznate ranjivosti uglavnom postoje u svim verzijama osim zadnjih izdanih.

Kada smo svjesni da imamo verziju OpenSSL-a za koju znamo da je ranjiva i na koji način, na nama je da odlučimo hoćemo li je nastaviti koristiti ili ne; može se dogoditi, primjerice, da nam ta ranjivost ne predstavlja problem jer se ona nalazi u implementaciji algoritma koji ne koristimo ili može biti slučaj da se kriptografijom na računalu bavimo isključivo u edukativne svrhe.

Note

Specijalno, ako koristimo OpenSSL pakiran od strane neke distribucije Linuxa ili drugog operacijskog sustava sličnom Unixu, moguće je da verzija koju imamo uključuje zakrpe poznatih ranjivosti dodane od strane distributera. Štoviše, može se dogoditi da broj verzije sugerira da ranjivosti i dalje postoje, a da to nije slučaj te je potrebno detalje o zakrpanim ranjivostima dodatno provjeriti kod distributer. Primjerice, za Debian se takve informacije za OpenSSL mogu naći u Security Bug Trackeru.

OpenSSL ima mnogo različitih naredbi. Listu postojećih naredbi možemo vidjeti opcijom help, čiji ispis započinje standardnim naredbama:

$ openssl help
Standard commands
asn1parse         ca                ciphers           cms
crl               crl2pkcs7         dgst              dhparam
enc               engine            errstr            gendsa
...

Slijedi lista naredbi za hashiranje:

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md2
md4               md5               rmd160            sha1
sha256            sha3-224          sha3-256          sha3-384
...

Naposlijetku je lista naredbi za šifriranje:

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb
aes-256-cbc       aes-256-ecb       aria-128-cbc      aria-128-cfb
aria-128-cfb1     aria-128-cfb8     aria-128-ctr      aria-128-ecb
...

Neke od naredbi već u imenima sugeriraju implementaciju ranije navedenih kriptografskih algoritama koje OpenSSL podržava.

Hashiranje i kriptografski sažetak

Hashiranje je proces preslikavanja skupa podataka proizvoljne veličine na skup podataka zadane veličine. Rezultat hashiranja nazivamo hash vrijednostima, hash kodovima, sažecima ili, jednostavno, hashevima.

Hashiranje datoteke

Hashiranje datoteke izvršava se pomoću opcije dgst, uz navođenje željenog algoritma. Primjerice, pogledajmo hashiranje tekstualne datoteke datoteka.txt koja sadrži izraz Hashiraj me! algoritmom MD5.

$ openssl dgst -md5 datoteka.txt
MD5(datoteka.txt)= bc838dd8ab805767036cbf99d5abd2b4

Za usporedbu, pogledajmo i hashiranje iste datoteke algoritmom SHA-1.

$ openssl dgst -sha1 datoteka.txt
SHA1(datoteka.txt)= d18fe411b275397fba802b307460d108483f626d

Također, moguće je hashirati sadržaj izravno sa standardnog ulaza. Primjerice, za hashiranje algoritmom SM3 naredba bi bila oblika:

$ echo "Hashiraj me!" | openssl dgst -sm3
(stdin)= f89e882b9c22d590f0f0a813f7352cfd857370151f96ad8cc45869274d8b981c

Više o dostupnim parametrima hashiranja možemo saznati naredbom openssl help dgst i na man stranici dgst(1ssl) (da, OpenSSL ima svoj odjeljak među stranicama man-a).

Kodiranje i dekodiranje

Osim šifriranja i dešifriranja, kao jednostavan uvodni primjer vrijedi spomenuti da OpenSSL podržava kodiranje i dekodiranje po shemi Base64. Za Base64 kodiranje sadržaja datoteke, koristimo -base64 opciju, uz parametar enc, te -in za ulaznu datoteku. Primjerice, za datoteku datoteka.txt sadržaja Omnium rerum principia parva sunt. naredba je oblika:

$ openssl enc -base64 -in datoteka.txt
T21uaXVtIHJlcnVtIHByaW5jaXBpYSBwYXJ2YSBzdW50Lgo=

Ukoliko želimo kodirani sadržaj spremiti u drugu datoteku, dodajemo parametar -out i naziv datoteke:

openssl enc -base64 -in datoteka.txt -out datoteka.txt.enc

Također je moguće kodirati tekstualni string izravno iz ljuske, primjerice korištenjem cijevi na način:

$ echo "Prima enim sequentem honestum est in secundis tertiisque consistere." | openssl enc -base64
UHJpbWEgZW5pbSBzZXF1ZW50ZW0gaG9uZXN0dW0gZXN0IGluIHNlY3VuZGlzIHRl
cnRpaXNxdWUgY29uc2lzdGVyZS4K

Obrnuto, moguće je dekodirati kodirani znakovni niz izravno iz ljuske naredbom oblika:

$ echo "UHJpbWEgZW5pbSBzZXF1ZW50ZW0gaG9uZXN0dW0gZXN0IGluIHNlY3VuZGlzIHRlcnRpaXNxdWUgY29uc2lzdGVyZS4K" | openssl enc -base64 -d
Prima enim sequentem honestum est in secundis tertiisque consistere.

Šifriranje i dešifriranje

Jednostavno šifriranje i dešifriranje

Ukoliko želimo šifrirati datoteku bez da koristimo ključeve ili certifikate, možemo to učiniti samo pomoću tajne zaporke i odabira željenog algoritma šifriranja. Algoritme možemo pregledati već spomenutom naredbom openssl help obraćajući pažnju na dio Cipher commands ili naredbom openssl enc -ciphers:

$ openssl enc -ciphers
Supported ciphers:
-aes-128-cbc               -aes-128-cfb               -aes-128-cfb1
-aes-128-cfb8              -aes-128-ctr               -aes-128-ecb
-aes-128-ofb               -aes-192-cbc               -aes-192-cfb
...

Pri svakom šifriranju, potrebno je upisati i potvrditi zaporku kojom ćemo zaštititi naše datoteke. Uz parametar šifriranja enc, te uz parametar željenog algoritma šifriranja, koristimo -in za ulaznu datoteku, te -out za izlaznu datoteku:

$ openssl enc -bf-cbc -in datoteka.txt -out datoteka.txt.enc
enter bf-cbc encryption password:
Verifying - enter bf-cbc encryption password:

Ovdje vršimo šifriranje tekstualne datoteke datoteka.txt u datoteka.txt.enc korištenjem algoritma Blowfish u obliku CBC (parametar -bf-cbc). Novije verzije OpenSSL-a uz izvršavanje traženog šifriranja će dati upozorenje:

*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.

Ovo nije ovisno o korištenom algoritmu šifriranja i njegovom obliku, primjerice isto bi dobili da smo koristili algoritam SM4 u obliku ECB (parametar -sm4-ecb). Parametrom -pbkdf2 uključuje se Password-Based Key Derivation Function 2 (PBKDF2), metoda izvođenja ključa (engl. key derivation method) iz zaporke koja je otpornija na napade grubom silom (engl. brute force attacks). Parametar -iter određuje broj iteracija primjene metode na unesenu zaporku. Što je broj iteracija veći, to će napadi grubom silom biti teži.

Pri šifriranju možemo birati hoćemo li dodatno enkodirati podatke iz datoteke shemom Base64. Ukoliko ne enkodiramo, rezultat će umjesto šifriranog sadržaja u tekstualnoj datoteci biti šifrirana binarna datoteka. Dodatno Base64 enkodiranje je nužno želimo li šifrirani sadržaj datoteke poslati elektorničkom poštom ili u situaciji gdje želimo imati šifrirani sadržaj u tekstualnom obliku. U tom slučaju dodajemo parametar -a, dok je ostatak sintakse naredbe isti:

$ openssl enc -aes-192-ecb -a -in datoteka.txt -out datoteka.txt.enc
enter aes-192-ecb encryption password:
Verifying - enter aes-192-ecb encryption password:

Ovdje vršimo šifriranje tekstualne datoteke datoteka.txt u datoteka.txt.enc korištenjem algoritma AES-192 u obliku ECB (parametar -aes-192-ecb).

Dešifriranje šifrirane datoteke vrši se na sličan način kao šifriranje (uz obavezno navođenje istog algoritma u istom obliku), no koristeći -d parametar. Parametar -a je opcionalan, ovisno o tome jesmo li prethodno Base64 enkodirali sadržaj datoteke:

$ openssl enc -aes-192-ecb -a -d -in datoteka.txt.enc
enter aes-192-ecb decryption password:

Više o dostupnim parametrima šifriranja i Base64 kodiranja možemo saznati naredbom openssl help enc i na man stranici enc(1ssl).

Hashirane zaporke

Koristeći opciju passwd, možemo stvoriti hashirane zaporke koje su kompatibilne s datotekama /etc/passwd i /etc/shadow na Linuxu i drugim operacijskim sustavima sličnim Unixu.

$ openssl passwd Tajna
vteVctKq72PqU

Pokrenemo li naredbu više puta, uočit ćemo da je rezultat uglavnom različit.

$ openssl passwd Tajna
2cr2FTlyj3TIg

Razlog tome je soljenje (engl. salting) zaporke koje uz samu zaporku kao ulazni podatak za hashiranje dodaje i dodatne slučajne znakove, takozvanu sol (engl. salt). Specijalno, zadani algoritam crypt (parametar -crypt) koristi sol (parametar -salt) duljine dva znaka i, ako parametar eksplicitno ne navedemo (kako smo napravili u primjerima iznad), sol se slučajno generira.

$ openssl passwd -salt OI Tajna
OIOp/K0E64/6o

Uočimo da su prva dva znaka u izlazu upravo sol, pa hashiranja gdje sol nije bila navedena možemo dobiti navođenjem redom soli vt i 2c.

Osim crypta, podržani algoritmi su i BSD-ov password algorithm 1 (parametar -1), Apachejeva varijanta istog algoritma apr1 (parametar -apr1), AIX-ova varijanta istog algoritma AIX MD5 (parametar -aixmd5) duljine soli do 8 znakova te algoritmi zasnovani na SHA256 i SHA512 čiji je autor Ulrich Drepper (parametri -5 i -6, respektivno) duljine soli do 16 znakova.

$ openssl passwd -apr1 -salt mojasol1 Tajna
$apr1$mojasol1$8WViPLbkVe9uEismjXvYL0

$ openssl passwd -5 -salt mojasolduga16znk Tajna
$5$mojasolduga16znk$6DR9NnCHR/RQRU2wVOUKeATv2l8xG4.1127EkHrl/O1

Više o dostupnim parametrima hashiranja zaporki možemo saznati naredbom openssl help enc i na man stranici passwd(1ssl).