Autor sekcije: Domagoj Margan, Vedran Miletić

Šifriranje podataka, certifikati i kriptografski sažeci

Alat OpenSSL

OpenSSL je open source implementacija SSL i TLS protokola. Koristi se za enkripciju datoteka, enkripciju javnih ključeva, digitalno potpisivanje, stvaranje i povlačenje certifikata, testiranje SSL veza, te brojne druge kriptografske funkcije. Kao CLI alat, podržava velik broj različitih operacijskih sustava uključujući Linux, Microsoft Windows, *BSD, Mac OS X i Solaris.

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

OpenSSL koristimo upisivanjem naredbe openssl u ljusic, uz odgovarajuće parametre i argumente.

OpenSSL dolazi instaliran na većini Linux distribucija. Kako bi provjerili koja je verzija instaliranja na sustavu, koristimo opciju version:

$ openssl version
OpenSSL 1.0.0d 8 Feb 2011

OpenSSL ima mnogo različitih naredbi. Listu standardnih naredbi možemo vidjeti opcijom list-standard-commands:

$ openssl list-standard-commands
asn1parse
ca
ciphers
cms
crl
crl2pkcs7
dgst
...

Za listu naredbi za šifriranje, koristimo list-cipher-commands:

$ openssl list-cipher-commands
aes-128-cbc
aes-128-ecb
aes-192-cbc
aes-192-ecb
aes-256-cbc
aes-256-ecb
base64
bf
bf-cbc
bf-cfb
bf-ecb
bf-ofb
camellia-128-cbc
camellia-128-ecb
...

Za listu naredbi za hashiranje, koristimo list-message-digest-commands:

$ openssl list-message-digest-commands
md4
md5
rmd160
sha
sha1

Kodiranje i dekodiranje

Osim šifriranja i dešifiriranja, kao jednostavan uvodni primjer vrijedi spomenuti da OpenSSL podržava Base64 kodiranje i dekodiranje. Za Base64 kodiranje sadržaja datoteke, koristimo -base64 opciju, uz parametar enc, te -in za ulaznu datoteku:

$ openssl enc -base64 -in datoteka.txt
UmVkV2lraSBqZSBtYWprYSBtdWRyb3N0aS4K

Datoteka datoteka.txt pritom ima sadržaj "RedWiki je majka mudrosti.". 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 "enkodiraj me" | openssl enc -base64
ZW5rb2RpcmFqIG1lCg==

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

$ echo "ZW5rb2RpcmFqIG1lCg==" | openssl enc -base64 -d
enkodiraj me

Šifriranje i dešifriranje

Jednostavno šifriranje i dešifriranje

Ukoliko želimo enkriptirati datoteku bez da koristimo ključeve ili certifikate, možemo to učiniti samo pomoću tajne lozinke i odabira željenog algoritma enkripcije (algoritme možemo pregledati već spomenutom naredbom openssl list-cipher-commands). Pri svakom enkriptiranju, potrebno je upisati i potvrditi lozinku kojom ćemo zaštititi naše datoteke.

Uz parametar enkripcije enc, te uz parametar željenog algoritma enkripcije, 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 enkriptiranje tekstualne datoteke datoteka.txt u datoteka.txt.enc korištenjem BlowFish algoritma u CBC obliku.

Pri enkriptiranju možemo birati hoćemo li dodatno 64-base enkodirati podatke iz datoteke. Ukoliko ne enkodiramo, rezultat će umjesto enkriptiranog sadržaja u tekstualnoj datoteci biti enkriptirana binarna datoteka. Dodatno 64-base enkodiranje je nužno želimo li enkodirani sadržaj datoteke poslati elektorničkom poštom ili u situaciji gdje želimo imati enkodirani 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 enkriptiranje tekstualne datoteke datoteka.txt u datoteka.txt.enc korištenjem AES-192 algoritma u ECB obliku.

Dekripcija enkriptirane datoteke vrši se na sličan način kao enkripcija, no koristeći -d parametar. Parametar -a je opcionalan, ovisno o tome jesmo li prethodno 64-base enkodirali sadržaj datoteke:

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

Haširane zaporke

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

$ openssl passwd Tajna
vteVctKq72PqU

Rad s ključevima

Generiranje (tajnih) RSA ključeva

Za generiranje RSA ključa koristimo genrsa opciju:

$ openssl genrsa
Generating RSA private key, 512 bit long modulus
..++++++++++++
..++++++++++++
e is 65537 (0x10001)
-----BEGIN RSA PRIVATE KEY-----
MIIBOQIBAAJBAKKzs/f8QudUR73fmeEerzDmrv+TJ9+k2LDuRMAKDCNTZTBhdLCO
81OwGJ6zM3eWblq1AoIVe/hqJo/lqwlBnYkCAwEAAQJACKJszJ5QlqI8ZHE3Y2ET
fw7e/qU6mn3PGiSq9V4TItS2eqCEwJkmFq7CmDIA861JDVUdHUbBQz336YRwK/4N
YQIhANdTKJ73+qqcOIlKKNBliFycEcXjIvT9Q6DhZBo0VLrdAiEAwW/EgpvOh3DR
9d2yfb0+crYQUqyRGsf6Rh/VNEn81J0CIEk6bsYhb442MsP+BINbBFT6ftDdvjWz
LBy6imCfC3HBAiAhy58vmn0Y2LM3G4elxDx22i1IQG8ZPrsRKVqcjORJWQIgMheM
xDmm2hNCmyC86VYIaqmrTKVJ7IyyurZiJ9KrVoc=
-----END RSA PRIVATE KEY-----

Ovdje generiramo 512-bitni ključ koji ispisujemo na standardni izlaz. Ukoliko želimo spremiti ključ u posebnu izlaznu datoteku, koristimo parametar -out:

$ openssl genrsa -out mojkljuc.pem 1024
Generating RSA private key, 1024 bit long modulus
...++++++
..++++++
e is 65537 (0x10001)

Ovime smo generirali 1024-bitni ključa i spremili ga u datoteku mojkljuc.pem. Želimo li osigurati naš ključ, možemo ga enkriptirati i zaštititi lozinkom. Dodajemo parametar željenog algoritma za enkripciju:

$ openssl genrsa -camellia256 -out mojkljuc.pem 1024
Generating RSA private key, 1024 bit long modulus
................................................++++++
............++++++
e is 65537 (0x10001)
Enter pass phrase for mojkljuc.pem:
Verifying - Enter pass phrase for mojkljuc.pem:

Ovime smo generirali 1024-bitni ključ i spremili ga u datoteku mojkljuc.pem, uz enkripciju Camellia-256 algoritmom.

Generiranje javnih RSA ključeva

Kako bi generirali pripadni javni ključ našeg privatnog RSA ključa, koristimo opcije rsa i -pubout:

$ openssl rsa -in mojkljuc.pem -pubout
Enter pass phrase for mojkljuc.pem:
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCauuMYe+ydopSs9mOZnFygjjx
Uhi+lLGedEGH491KVy0QW9JKKbWaLVsPkLilw0OxKwDOVc6yBnvDdYW8RK8E+OeJ
XLJh24kWebOw9vM7GOCbawSXNwe2D7isEGygQJ4Q9bVXQrvDeaSTudyu4fclEeun
uUEykhppZK8yTFmMaQIDAQAB
-----END PUBLIC KEY-----

Generiranje DSA ključeva

Generiranje DSA ključeva izvodi se putem opcija dsaparam i genkey. Pokažimo stvaranje 1024-bitnog ključa u datoteci dsakljuc.pem.

openssl dsaparam -out dsakljuc.pem -genkey 1024
Generating DSA parameters, 1024 bit long prime
This could take some time
.....+.............+++++++++++++++++++++++++++++++++++++++++++++++++++*
.+..........+.......+................+.......+......+.........+...........+........+..........+.........+...........+.+.......+...................+..........+........+...+..+....+++++++++++++++++++++++++++++++++++++++++++++++++++*

Generiranje ključeva algoritmom eliptične krivulje

Za generiranje ključeva algoritmom eliptične krivulje, koriste se opcije ecparam, -name i genkey. Pokažimo stvaranje ključa u datototeci krivulja.pem korištenjem eliptične krivulje sect571r1.

$ openssl ecparam -out krivulja.pem -name sect571r1 -genkey

Opcijom -name određujemo krivulju, te je nužno navesti željeni algoritam. Listu možemo vidjeti navođenjem ecparam -list_curves:

$ openssl ecparam -list_curves
  secp112r1 : SECG/WTLS curve over a 112 bit prime field
  secp112r2 : SECG curve over a 112 bit prime field
  secp128r1 : SECG curve over a 128 bit prime field
  secp128r2 : SECG curve over a 128 bit prime field
  secp160k1 : SECG curve over a 160 bit prime field
  secp160r1 : SECG curve over a 160 bit prime field
  secp160r2 : SECG/WTLS curve over a 160 bit prime field
  secp192k1 : SECG curve over a 192 bit prime field
  secp224k1 : SECG curve over a 224 bit prime field
  secp224r1 : NIST/SECG curve over a 224 bit prime field
  secp256k1 : SECG curve over a 256 bit prime field
  secp384r1 : NIST/SECG curve over a 384 bit prime field
  secp521r1 : NIST/SECG curve over a 521 bit prime field
  prime192v1: NIST/X9.62/SECG curve over a 192 bit prime field
  prime192v2: X9.62 curve over a 192 bit prime field
  prime192v3: X9.62 curve over a 192 bit prime field
  prime239v1: X9.62 curve over a 239 bit prime field
  prime239v2: X9.62 curve over a 239 bit prime field
  prime239v3: X9.62 curve over a 239 bit prime field
  prime256v1: X9.62/SECG curve over a 256 bit prime field
  sect113r1 : SECG curve over a 113 bit binary field
  sect113r2 : SECG curve over a 113 bit binary field
  sect131r1 : SECG/WTLS curve over a 131 bit binary field
  sect131r2 : SECG curve over a 131 bit binary field
  sect163k1 : NIST/SECG/WTLS curve over a 163 bit binary field
  sect163r1 : SECG curve over a 163 bit binary field
  sect163r2 : NIST/SECG curve over a 163 bit binary field
...

Rad s certifikatima

Todo

Ovdje nedostaje paragraf ili dva o certifikatima.

Generiranje samopotpisanih certifikata

Generiranje samopotpisanog certifikata (engl. self-signed certificate) zbog složenosti zahtjeva uporabu više opcija i parametara.

Idući primjer pokazuje generiranje datoteke nazvane mojcertifikat.pem, koji će sadržavati privatni ključ i javni certifikat baziran na privatnome ključu. Moguće je odrediti broj dana valjanosti certifikata (u ovom slučaju 365), te hoće li ključ biti enkriptiran (opcija -nodes isključuje enkripciju). Pri stvaranju certifikata potrebno je odgovoriti na nekoliko pitanja kojima se u certfikat unose informacije o vlasniku.

$ openssl req -x509 -nodes  -days 365 -newkey rsa:1024 -keyout mojcertifikat.pem -out mojcertifikat.pem
Generating a 1024 bit RSA private key
.........................++++++
.................................................................++++++
writing new private key to 'mojcertifikat.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:
Email Address []:

Provjera certifikata

Za provjeru certifikata koristi se opcija verify. Ukoliko lokalna OpenSSL instalacija prepozna certifikat i potpis, vraća se povratna poruka OK.

$ openssl verify valjani-certifikat.pem
OK

Ukoliko se pak pronađe problem sa certifikatom, javlja se obavijest o tome uz kratak opis problema, primjerice:

$ openssl verify sampotpisani-certifikat.pem
error 18 at 0 depth lookup:self signed certificate

Ukoliko se ne napravi iznimka, OpenSSL neće verificirati sampotpisani certifikat. Certifikati su najčešće predodređeni za konkretni vremenski period, te OpenSSL javlja grešku ukoliko je taj period istekao.

$ openssl verify sampotpisani-certifikat.pem
error 10 at 0 depth lookup:certificate has expired

Rad sa sigurnim poslužiteljima

Za ostvarivanje SSL veze s poslužiteljima i testiranje istih, koristimo opciju s_client i parametar -connect. Poslužitelj mora imati omogućeno SSL pristupanje. Opciju s_client koristimo pri dijagnosticiranju problema sigurnih servera.

Primjerice, za HTTP preko SSL-a:

$ openssl s_client -connect remote.host:443

Za SMTP preko SSL-a:

$ openssl s_client -connect remote.host:465

Za IMAP preko SSL-a:

$ openssl s_client -connect remote.host:993

Za POP-3 preko SSL-a:

$ openssl s_client -connect remote.host:995

Za LDAP preko SSL-a:

$ openssl s_client -connect remote.host:636

Nakon spajanja mougće je unositi naredbe. Konkretno, ukoliko smo ostvarili HTTPS vezu, moguće je unositi uobičajene HTTP naredbe (npr. GET i POST).

Za primjer se možemo spojiti HTTPS-om na Red Hat poslužitelj dostupan na adresi www.redhat.com.

$ openssl s_client -connect www.redhat.com:443
CONNECTED(00000003)
depth=1 C = US, O = Akamai Technologies Inc, CN = Akamai Subordinate CA 3
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/L=Raleigh/O=Red Hat, Inc/OU=IT/ST=NORTH CAROLINA/CN=*.redhat.com
   i:/C=US/O=Akamai Technologies Inc/CN=Akamai Subordinate CA 3
 1 s:/C=US/O=Akamai Technologies Inc/CN=Akamai Subordinate CA 3
   i:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICszCCAhygAwIBAgIOAgAAAAABNMoAVStzfTAwDQYJKoZIhvcNAQEFBQAwUTEL
MAkGA1UEBhMCVVMxIDAeBgNVBAoTF0FrYW1haSBUZWNobm9sb2dpZXMgSW5jMSAw
HgYDVQQDExdBa2FtYWkgU3Vib3JkaW5hdGUgQ0EgMzAeFw0xMjAxMTAyMzU2NDla
Fw0xMzAxMTAyMzU2NDlaMHMxCzAJBgNVBAYTAlVTMRAwDgYDVQQHEwdSYWxlaWdo
MRUwEwYDVQQKEwxSZWQgSGF0LCBJbmMxCzAJBgNVBAsTAklUMRcwFQYDVQQIEw5O
T1JUSCBDQVJPTElOQTEVMBMGA1UEAxQMKi5yZWRoYXQuY29tMIGfMA0GCSqGSIb3
DQEBAQUAA4GNADCBiQKBgQDNKUvU6JnElSX3i5z3+lZZsoInpXlnlYhE6owUKRjX
rGoN3GicuygCAnswxIOpElTL01zNx+sqTPYjZtt/JWg9pgwpP+JFbJQtrQl5Rs6F
hJiM2kUZCk3LDvQIxQoID54VLnw1DLImCAfwaTxqDdyST6ODWm6/RzbkZS21/ZYB
wwIDAQABo2wwajA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLmdsb2JhbHNp
Z24ubmV0L0FrYW1haVN1YjMuY3JsMB0GA1UdDgQWBBT4uW1EptOUFsMZOibN2oG5
pmTi/jAOBgNVHQ8BAf8EBAMCBSAwDQYJKoZIhvcNAQEFBQADgYEAC0WAfTm3IBVk
pBB27mQch9WJRD2w+Sl482q6lOwGzN5FwlyHY4W+uJ+FbzX5jLPzs3kk9BhrpOmL
5UCrxhIW3xO9JGWMU3AC/hj4Ul4QiaDPAma9GTOZnoZ6ECpCYguMnmHT07PMK1ML
oOzsuZqC1gD8ql4PUDt3MBGBcWXxNx8=
-----END CERTIFICATE-----
subject=/C=US/L=Raleigh/O=Red Hat, Inc/OU=IT/ST=NORTH CAROLINA/CN=*.redhat.com
issuer=/C=US/O=Akamai Technologies Inc/CN=Akamai Subordinate CA 3
---
No client certificate CA names sent
---
SSL handshake has read 1854 bytes and written 351 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : AES256-SHA
    Session-ID: 0D3987C5BCEE062D3984A6392D6055B07F34E075C4B309EE76FB170F43E32240
    Session-ID-ctx:
    Master-Key: 355547CEC9826C2FA87353D68596FFE61D449506AC8F45F18ED490D83925B22D32159F4126727405E5ED21B315415951
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1333934756
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---

Funkcije za haširanje i kriptografski sažeci

Todo

Ovdje također nedostaje paragraf ili dva teorijske pozadine.

Haširanje datoteke

Haširanje datoteke izvršava se pomoću dgst opcije, uz navođenje željenog algoritma. Primjerice, pogledajmo haširanje 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 haširanje iste datoteke algoritmom SHA-1.

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

Potpisivanje haširane datoteke

Ako se želimo osigurati da se stvorena haširana datoteka neće mijenjati bez naše dozvole, možemo je potpisati našim privatnim ključem. Koristimo opcije -sign za potpisivanje i -out za izlaznu datoteku. Potpisana datoteka bit će datoteka.txt.sha1.

$ openssl dgst -sha1 -sign mojkljuc.pem -out datoteka.txt.sha1 datoteka.txt

Provjeravanje potpisane haš datoteke

Za provjeru potpisane haš datoteke, potrebna je originalna datoteka iz koje je stvoren haš, potpisana haš datoteka i javni ključ potpisatelja. Koristimo parametar -verify za javni ključ, te -signature za potpisanu haš datoteku.

$ openssl dgst -sha1 -verify javnikljuc.pem -signature datoteka.txt.sha1 datoteka.txt