Laborator 08: Securitate: PKI și X.509

TLS (Transport Layer Security) reprezintă modul în care un canal TCP nesigur este securizat. TLS asigură un canal sigur (criptat) de comunicare între client și server. În general serverul își validează identitatea folosind un certificat care apoi este folosit și pentru stabilirea cheilor de criptare ale conexiunii.

Un certificat cuprinde o cheie publică, datele de identificare ale serverului și o semnătură care să garanteze asocierea între acea identitate și cheia publică aferentă.

Un certificat este valid dacă este semnat de o autoritate de certificare (CA: Certificate Authority). Această entitate este considerată de încredere de clientul comunicației, iar clientul are acces la certificatul acestei autorități. Cu certificatul acestei autorități, clientul poate verifica semnătura certificatului serverului și, astfel, să se asigure de identitatea serverului.

Investigarea unui certificat

În arhiva de sarcini a laboratorului există un certificat în fișierul houdini.cs.pub.ro.crt-roedunet.

Vrem să afișăm informații despre acest fișier: identificator, semnatar, data expirării, cheia publică. Pentru aceasta folosim comanda

openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -text

Parcurgeți output-ul comenzii și aflați informații despre certificat precum:

  • Semnatarul (issuer)
  • Intervalul de validitate
  • Modulul și exponentul
  • Subiectul (CN: Common Name)
  • Extensii ale certificatului
  • Cheia publică
  • Semnătura

Putem afișa informații punctuale despre certificat solicitând infomații punctuale (doar anumite câmpuri) folosind comanda openssl cu opțiunile aferente:

openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -pubkey
openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -startdate
openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -enddate
openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -dates
openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -issuer
openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -subject
openssl x509 -in houdini.cs.pub.ro.crt-roedunet -noout -modulus

Verificarea unui certificat

Vrem să verificăm faptul că un certificat este semnat valid și că avem acces corect la certificatul CA-ului (sau lanțul de certificate ale CA-ului – certificate chain). De obicei, serverul este configurat să trimită certificatele intermediare clientului pentru ca acesta să poată avea acces la întreg lanțul de certificate.

Verificăm certificatul de mai sus folosind comanda

openssl verify -CAfile ../../terena-ca-chain-2.pem security.cs.pub.ro.crt-roedunet

Certificatul apare expirat, dar din punctul de vedere al semnării este valid.

Pentru certificatele open-source.cs.pub.ro.crt-roedunet și security.cs.pub.ro.crt-roedunet verificați care este certificate chain-ul aferent cu care au fost generate. Adica vedeți care dintre cele două fișiere de tip chain (terena-ca-chain.pem și terena-ca-chain-2.pem sunt cele corespunzătoare.

Urmăriți ce conțin fișierele de tip chain folosind comanda cat.

Pentru a face dump la informațiile dintr-un fișier de tip bundle (cum sunt terena-ca-chain.pem și terene-ca-chain-2.pem) nu avem suport implicit în openssl. Putem însă folosi comanda keytool din suita Java, așa cum este indicat aici. Folosiți keytool pentru a afișa informații despre certificatele de tip bundle.

Conectarea sigură la un server

Pentru a testa conectarea sigură la un server și interogarea acestuia (similar comenzii netcat), vom folosi comanda openssl s_client care realizează un tunel sigur TLS.

Astfel, pentru a ne conecta la Google în modul simplu, vom folosi comanda

nc google.com 80
GET / HTTP/1.0

HTTP/1.0 302 Found
Location: http://www.google.ro/?gws_rd=cr&ei=i2qOVpSiAuLnyQPYkaO4AQ
Cache-Control: private
[...]

în vreme ce pentru a ne conecta în mod sigur folosim comanda

openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = *.google.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIHqTCCBpGgAwIBAgIILjRo+RchlW0wDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
[...]
---
GET / HTTP/1.0

HTTP/1.0 302 Found
Location: https://www.google.ro/?gws_rd=cr&ei=pWqOVq7vEcO8ygOarIi4DQ
Cache-Control: private
[...]

Observăm că în cazul conexiunii sigure, am primit și informații despre certificatul google.com, conexiunea este acum sigură, dar rezultatul este același (am obținut aceeași pagină).

Pentru a valida siguranța conexiunii putem, într-o consolă distinctă, să capturăm traficul folosind tcpdump cu ajutorul comenzii de mai jos:

sudo tcpdump -i eth0 -n -A host google.com and tcp port 80 or tcp port 443

Înlocuiți eth0 cu interfața activă a sistemului.

Dacă reluăm comenzile de mai sus vom vedea că putem vizualiza cererea și răspunsul HTTP pentru conexiunea plain text (folosind netcat) dar nu și pentru cererea și răspunsul HTTPS pentru conexiunea sigură.

Puteți valida faptul că o conexiune este sigură sau nu și prin folosirea comenzii wget:

wget http://google.com
wgets http://google.com

Folosiți openssl s_client pentru a obține pagina acestui laborator, adică folosiți URL-ul https://ocw.cs.pub.ro/courses/gsr/laboratoare/laborator-08. Observați că se face redirectarea acelei adrese către adresa fără HTTPS.

Investigarea unui certificat la distanță

După cum am observat mai sus, conectarea cu openssl s_client permite obținerea certificatelor de la distanță. Putem astfel obține un certificat la distanță folosind comanda

echo | openssl s_client -connect open-source.cs.pub.ro:443

Observăm că am obținut certificatul pentru koala.cs.pub.ro întrucât serverul folosește virtual hosting. Ca să activăm suportul de SNI, atunci folosim opțiunea -servername:

echo | openssl s_client -connect open-source.cs.pub.ro:443 -servername open-source.cs.pub.ro

Pentru a obține doar certificatul aferent serverului de la distanță (open-source.cs.pub.ro) folosim comanda

echo | openssl s_client -connect open-source.cs.pub.ro:443 -servername open-source.cs.pub.ro 2> /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

Apoi, ca să investigăm, direct certificatul folosim comanda openssl x509. Dacă ne interesează doar subiectul și datele vom folosi comanda

echo | openssl s_client -connect open-source.cs.pub.ro:443 -servername open-source.cs.pub.ro 2> /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | openssl x509 -noout -subject -dates

Realizați același lucru și pentru server-ul de cursuri (cs.curs.pub.ro) pentru serverul systems.cs.pub.ro și pentru un alt server la alegere. Observați dacă sunt valide, care este issuer-ul și care este data de expirare.

Generarea și semnarea unui certificat

Dorim să trecem prin toți pașii de generare, obținere și folosire a unui certificat. Adică:

  • Alegem fiecare un nume de domeniu.
  • Vom genera o cheie privată și o cerere de semnare (CSR: certificate signing request).
  • Vom solicita crearea unui certificat pe baza CSR-ului către un CA. În cazul nostru va fi vorba de un sistem din laborator care semnează.
  • Vom obține de la CA certificatul semnat.

Pentru început fiecare dintre voi alege un nume de domeniu care să fie <nume>.ixlabs. Discutați în prealabil cu asistentul ce nume să alegeți pentru a fi siguri că nu apar conflicte. <nume> poate fi prenumele vostru, o poreclă sau alt nume care vă place vouă.

Mai jos vom folosi numele dorel.ixlabs pe care să îl înlocuiți voi cu numele vostru.

Apoi creați cheia privată folosind acest nume

openssl genrsa -out dorel.ixlabs.key 2048

După ce am generat cheia o putem investiga folosind comenzi precum

openssl rsa -in dorel.ixlabs.key -noout -text
openssl rsa -in dorel.ixlabs.key -noout -modulus

Având cheia generată, acum putem genera CSR-ul aferent:

openssl req -new -key dorel.ixlabs.key -out dorel.ixlabs.csr

Folosiți ca

  • Organizational Name: Ixia
  • Organizational Unit Name: Development
  • Common Name: folosiți numele vostru de domeniu

Lăsați goale (dați Enter) pentru Challenge assword și Optional Company Name.

Apoi putem investiga CSR-ul folosind comanda

openssl req -in dorel.ixlabs.csr -noout -text

Acum avem CSR-ul pe care să îl trimitem către CA pentru semnare.

Vom simula CA-ul pe un sistem din laborator. Veți copia CSR-ul pe sistemul în cauză pentru semnare. Pentru aceasta folosiți SSH cu o comandă de forma:

scp dorel.ixlabs student@<adresa-IP-CA>:certs/

unde <adresa-IP-CA> este adresa IP a CA-ului indicată pe tablă.

Apoi mergeți la asistent pentru a solicita semnarea certificatului și spuneți care este certificatul vostru.

După ce este semnat certificatul, copiați-l înapoi folosind tot SSH. Copiați și certificatul CA-ului.

Verificarea unui certificat și a cheii private

Pentru a verifica faptul că certificatul obținut (să spunem că este dorel.ixlabs.crt) va trebui să comparăm modulul său (al cheii publice) și modulul cheii private.

Pentru aceasta putem folosi comenzile

openssl rsa -in dorel.ixlabs.key -noout -modulus | md5sum
openssl x509 -in dorel.ixlabs.crt -noout -modulus | md5sum

Dacă cele două rezultate corespund înseamnă că certificatul este valid și este corepunzător cheii private. Acum poate fi folosit într-o configurare pe un servere care să asigure o conexiune TLS.

Realizați verificarea certificatului pentru houdini.cs.pub.ro și a cheii private aferente folosind comenzi similare celor de mai sus.

gsr/laboratoare/laborator-08.txt · Last modified: 2016/12/14 20:46 by alexandru.carp
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0