Sistem de Autentificare, Autorizare Si Control al Accesului In Sistemele Distribuite
CUPRINS
TOC \o 1-1 \t "Heading #2, 2,Heading #3, 3,Heading 2 + Times New Roman, 4,Heading 3, 5"
ADNOTARE PAGEREF _Toc \h 4
ABSTRACT PAGEREF _Toc1 \h 5
АННОТАЦИЯ PAGEREF _Toc2 \h 6
LISTA ABREVIERILOR PAGEREF _Toc3 \h 7
INTRODUCERE PAGEREF _Toc4 \h 9
1. STUDIU ASUPRA METODELOR MODERNE DE AUTENTIFICARE, AUTORIZARE ȘI ACONTROL ALA ACCESULUI PAGEREF _Toc5 \h 11
1.1 Noțiuni generale ale Criptografiei PAGEREF _Toc6 \h 11
1.1.1 Criptografia simetrică PAGEREF _Toc7 \h 11
1.1.2 Criptografia asimetrică PAGEREF _Toc8 \h 12
1.1.3 Funcții hash PAGEREF _Toc9 \h 14
1.2 Protocoale de securitate PAGEREF _Toc10 \h 14
1.2.1 Principii de proiectare PAGEREF _Toc11 \h 15
1.2.2 Proiectare via teste de autentificare PAGEREF _Toc12 \h 19
1.2.3 Independența protocoalelor de securitate PAGEREF _Toc13 \h 20
1.3 Infrastructura Cheilor Publice (PKI) PAGEREF _Toc14 \h 21
1.3.1 Certificatele X.509 PAGEREF _Toc15 \h 21
1.4 Mecanismul Single Sign-On (SSO) PAGEREF _Toc16 \h 22
1.5 Ingineria programării bazată pe componente (CBSE) PAGEREF _Toc17 \h 23
1.5.1 Application Programming Interface (API) PAGEREF _Toc18 \h 23
1.6 Platforma Mozilla PAGEREF _Toc19 \h 24
1.6.1 Arhitectura Mozilla PAGEREF _Toc20 \h 25
1.6.2 XPCOM PAGEREF _Toc21 \h 26
1.7. Concluzii la compartimentul 1 PAGEREF _Toc22 \h 26
2. PROIECTAREA SISTEMULUI PAGEREF _Toc23 \h 27
2.1 Cerințe PAGEREF _Toc24 \h 27
2.2 Arhitectura sistemului PAGEREF _Toc25 \h 28
2.2.1 Proiectarea mecanismului Single Sign-on PAGEREF _Toc26 \h 28
2.2.2 Componentele sistemului PAGEREF _Toc27 \h 30
2.2.3 Proiectarea componentei XServer PAGEREF _Toc28 \h 31
2.2.4 Proiectarea componentei XClient PAGEREF _Toc29 \h 34
2.2.5 Proiectarea bazei de date PAGEREF _Toc30 \h 36
2.3 Proiectarea interfeței de programare (API) PAGEREF _Toc31 \h 36
2.4 Proiectarea protocoalelor de securitate PAGEREF _Toc32 \h 39
2.4.1 Protocolul de autentificare la home server PAGEREF _Toc33 \h 39
2.4.2 Protocolul de autentificare la serverul de resurse PAGEREF _Toc34 \h 41
2.4.3 Protocolul de solicitare certificat PAGEREF _Toc35 \h 42
2.5. Concluzii la compartimentul 2 PAGEREF _Toc36 \h 42
3. IMPLEMENTAREA SISTEMULUI PAGEREF _Toc37 \h 43
3.1. Arhitectura internă a claselor PAGEREF _Toc38 \h 43
3.1.1 Clasele de bază PAGEREF _Toc39 \h 44
3.1.2. Clasele de securitate PAGEREF _Toc40 \h 46
3.1.3. Canalele de comunicație PAGEREF _Toc41 \h 47
3.1.4. Servicii PAGEREF _Toc42 \h 49
3.2. XServer PAGEREF _Toc43 \h 49
3.2.1 Serviciul de autentificare PAGEREF _Toc44 \h 50
3.2.2. Serviciul de resurse PAGEREF _Toc45 \h 52
3.3. XClient PAGEREF _Toc46 \h 53
3.4. Implementarea API-ului PAGEREF _Toc47 \h 55
3.5. Rezultate experimentale PAGEREF _Toc48 \h 56
3.6. Concluzii la compartimentul 3. PAGEREF _Toc49 \h 57
CONCLUZII GENERALE ȘI RECOMANDĂRI PAGEREF _Toc50 \h 58
BIBLIOGRAFIE PAGEREF _Toc51 \h 60
ANEXĂ PAGEREF _Toc52 \h 62
Aprob
Șef Catedră TIC
Iuri Dubcovețchi, dr., conf. univ.
_________________________
”___” ________________ 2014
S A R C I N A
pentru teza de licență a studentului grupei IA-33 Hîncu Valentin
Tema: „Sistem de autentificare, autorizare și control al accesului în sistemele distribuite”
aprobată prin ordinul nr____ din ”___” _____________ 2014
Conținutul notei explicative: 1. Analiza algoritmilor, metodelor și sistemelor clasice și moderne de autentificare, autorizare și control al accesului în sistemele distribuite. 2. Elaborarea și realizarea unui algoritm de autentificare, autorizare și control al accesului în sistemele distribuite. 3. Analiza algoritmului elaborat.
Lista materialului grafic: 1. Clasificarea algoritmilor, metodelor și sistemelor existente de autentificare, autorizare și control al accesului în sistemele distribuite. 2. Structura algoritmului nou de criptare de autentificare, autorizare și control al accesului în sistemele distribuite. 3. Schema-bloc al softului elaborat; 4. Rezultatele cercetărilor și testărilor algoritmului elaborat.
Data înmânării sarcinii: ”___” _____________ 2014.
Executant
Hîncu Valentin,
Studentul grupei IA-33
Conducătorul tezei
Aureliu Zgureanu, dr. conf. univ.
ADNOTARE
Hîncu Valentin, „Sistem de autentificare, autorizare și control al accesului în sistemele distribuite”, teză de licență la specialitatea Informatică Aplicată, Chișinău, 2014.
Proiectul cuprinde introducerea, trei capitole, concluzii cu recomandări, bibliografia din 31 titluri. Ea este perfectată pe 82 pagini, conține 44 figuri și 1 tabel.
Cuvinte-cheie: autentificare, access control, autorizare, sistem distribuit.
Domeniul de studiu al tezei este securitatea sistemelor informatice.
Scopul și obiectivele lucrării constau în cercetarea, proiectarea și configurarea unui sistem pentru autentificare, autorizare și control al accesului într-un sistem distribuit.
Noutatea și originalitatea lucrării constă în folosirea componentelor XPCOM, pentru a încapsula nivelul de transport.
Semnificația teoretică a lucrării constă în dezvoltarea unui middleware care implementează protocoalele de securitate și mecanismul single sign-on.
Valoarea aplicativă a lucrării constă faptul că acest sistem poate fi implementat în diverse companii care au câteva filiale.
Implementarea rezultatelor obținute. Sistemul realizat a fost configurat și testat pentru rețelele de calculatoare ale firmei „Acasă la mama”, care deține o rețea de restaurante.
ABSTRACT
Hîncu Valentin, „System for authentication, authorization and access control in distributed systems” thesis for specialty Applied Informatics, Chisinau, 2014.
The thesis contains the introduction, three chapters, conclusions and recommendations, bibliography of 31 titles. It consists of 82 pages, including 44 figures and 1 table.
Keywords: authentication, access control , authorization, distributed system.
Field of study of the thesis is security of information systems.
Goals and objectives are to research, design and configure a system for authentication, authorization and access control in a distributed system.
Novelty and originality of this work is use of XPCOM components to encapsulate the transport level.
The theoretical significance of the paper is developation of a middleware that implements security protocols and a single sign -on mechanism.
Applicative value of the work is that this system can be implemented in various companies that have several branches.
Implementation results. The developed system has been configured and tested in computer networks of company „Acasă la mama” which is composed from a network of restaurants.
АННОТАЦИЯ
Хынку Валентин, „Cистема аутентификации, авторизации и контроля доступа в распределенных системах”, дипломная работа по специальности Прикладная Информатика, Кишинев 2014.
Проект включает введение, три главы, выводы и рекомендации, библиографию из 31 наименований. Он выполнен на 82 страницах, содержит 44 фигуры и 1 таблицу.
Ключевые слова: аутентификация, управление доступом, авторизации, распределенная система.
Область исследования работы является безопасность информационных систем.
Цели и задачи работы состоят в исследовании, проектировании и настройке систем для аутентификации, авторизации и контроля доступа в распределенной системе.
Новизна и оригинальность работы заключается в использовании компонентов XPCOM для инкапсуляции транспортного уровня.
Теоретическая значимость работы заключается в разработке связующего программного обеспечения (middleware), реализующего протоколы безопасности и механизм единого входа.
Прикладная значимость работы является то, что эта система может быть реализована в различных компаниях, которые имеют несколько филиалов.
Результаты внедрения. Разработанная система была настроена и испытана на компьютерную сеть фирмы „Acasă la mama”, которая состоит из сети ресторанов.
LISTA ABREVIERILOR
AES – Advanced Encryption Standard
API – Application Programming Interface
MD5 – Message Digest Algorithm 5
MIT – Massachusetts Institute of Technology
NIST – National Institute of Standards and Technology
PKI – Public Key Infrastructure
RSA – Alogoritm criptografic cu cheie publică (autori Rivest, Shamir Adleman)
SHA1 – Secure Hash Algorithm
SSL – Secure Sockets Layer
SSO – Single Sign-On
XPCOM – Cross Platform Component Object Model
INTRODUCERE
Actualitatea și importanța problemei abordate. Importanța aspectelor de securitate în rețelele de calculatoare care stau la baza sistemelor distribuite a crescut și crește în continuare, odată cu extinderea prelucrărilor electronice de date și a transmiterii acestora prin intermediul rețelelor.
Scopul și obiectivele tezei. În cele mai multe sisteme distribuite și rețele de calculatoare, protecția resurselor se realizează prin login direct folosind parole, cu transmiterea în clar a acestora. Aceasta autentificare are mai multe inconveniențe, din care cea mai problematică ar fi expunerea parolei la captură pasivă. În zilele noastre vizitam zeci de website-uri, pe fiecare trebuie să ne cream un cont de utilizator, completând cu atenție formulare de înregistrare, să reținem parole, și să le introducem de fiecare dată când vrem să accesăm conținutul. Acest lucru devine plictisitor și repulsiv, și în același timp informațiile noastre confidențiale sunt expuse la potențiale atacuri de fiecare dată. Mulți dintre noi refolosim aceleași parole în mai multe locuri, crescând astfel riscul unui compromis neplăcut. În această lucrare propun un mecanism „Single Sign-On”, bazat pe certificate generate la solicitare de către aplicația client. Sistemele Single Sign-On (SSO) permit ca utilizatorii să-și introducă datele personale doar o singură dată, și să primească acces la multiple resurse în sistem.
Dezvoltarea rapidă a internetului și faptul că acesta este accesibil unui număr foarte mare de utilizatori a determinat un volum mare de date private aflat în circulație punându-se astfel problema securității datelor și a limitării accesului la date. Securitatea informației înseamnă protejarea informațiilor și a sistemelor informatice împotriva acțiunilor neautorizate în ceea ce privește accesul, folosirea, copierea, modificarea sau distrugerea datelor.
Transmisia de date dintre client și server se va realiza folosind canale de comunicații securizate, cu ajutorul protocoalelor de securitate și a criptografiei. Pentru a permite conectare rapidă la multiple resurse, nu am folosit protocoalele complexe existente, ca SSL, sau versiunea mai nouă, TLS, ci am construit un set de protocoale noi, pe baza testelor de autentificare descrise de Guttman [11, 14]. Aceste protocoale au fost implementate folosind librăriile de securitate OpenSSL, oferind performanță și confidențialitate [23, 29].
Importanța teoretică și valoarea aplicativă a lucrării. Pentru a pune în practică modelul propus, am dezvoltat un middleware care implementează aceste protocoale de securitate și mecanismul single sign-on. Majoritatea mecanismelor SSO existente pe care le-am analizat au un dezavantaj major: sunt implementate să funcționeze doar pe o singură platformă, cum ar fi Active Directory pentru Microsoft Windows, sau eDirectory pentru sistemele Unix [10, 16]. Un alt dezavantaj frecvent întâlnit este arhitectura centralizată, de exemplu LDAP, adică serverele de autentificare trebuie să fie conectate la un server central pentru a autentifica utilizatorii.
Noutatea științifico-practică a rezultatelor obținute constă în folosirea componentelor XPCOM, pentru a încapsula nivelul de transport. Astfel middleware-ul nu va fi restricționat pe o singură platformă și mecanismul single sign-on va fi disponibil pe orice platformă care suportă Mozilla. Pentru a nu depinde de un server central la autentificare, vom implementa componenta în fiecare server din rețea, adăugarea cărora se va putea face cu ușurință în caz de nevoie. Clienții se vor putea deplaește accesul, folosirea, copierea, modificarea sau distrugerea datelor.
Transmisia de date dintre client și server se va realiza folosind canale de comunicații securizate, cu ajutorul protocoalelor de securitate și a criptografiei. Pentru a permite conectare rapidă la multiple resurse, nu am folosit protocoalele complexe existente, ca SSL, sau versiunea mai nouă, TLS, ci am construit un set de protocoale noi, pe baza testelor de autentificare descrise de Guttman [11, 14]. Aceste protocoale au fost implementate folosind librăriile de securitate OpenSSL, oferind performanță și confidențialitate [23, 29].
Importanța teoretică și valoarea aplicativă a lucrării. Pentru a pune în practică modelul propus, am dezvoltat un middleware care implementează aceste protocoale de securitate și mecanismul single sign-on. Majoritatea mecanismelor SSO existente pe care le-am analizat au un dezavantaj major: sunt implementate să funcționeze doar pe o singură platformă, cum ar fi Active Directory pentru Microsoft Windows, sau eDirectory pentru sistemele Unix [10, 16]. Un alt dezavantaj frecvent întâlnit este arhitectura centralizată, de exemplu LDAP, adică serverele de autentificare trebuie să fie conectate la un server central pentru a autentifica utilizatorii.
Noutatea științifico-practică a rezultatelor obținute constă în folosirea componentelor XPCOM, pentru a încapsula nivelul de transport. Astfel middleware-ul nu va fi restricționat pe o singură platformă și mecanismul single sign-on va fi disponibil pe orice platformă care suportă Mozilla. Pentru a nu depinde de un server central la autentificare, vom implementa componenta în fiecare server din rețea, adăugarea cărora se va putea face cu ușurință în caz de nevoie. Clienții se vor putea deplasa liber la aceste servere, distribuind sarcina produsă de procesul de autentificare pe toate nodurile din rețea.
Sumarul compartimentelor tezei. Teza de față conține introducere, trei capitole, concluzii cu recomandări, lista bibliografică din 30 titluri și anexa. Ea este perfectată pe 82 pagini, dintre care 47 pagini constituie partea de bază, conține 44 figuri și 1 tabel.
Capitolul 1 prezintă câteva noțiuni despre criptografie, tipurile ei, diferențele dintre cea simetrică și asimetrică, și folosirea acestora. Se continuă cu descrierea protocoalelor de securitate, principii de proiectare, testele de autentificare și independența protocoalelor. Urmează o prezentare a infrastructurii cheilor publice, și descrierea certificatelor X.509. Capitolul continuă cu un subcapitol despre mecanismul Single Sign-On, și principiile ingineriei programării bazate pe componente. În încheierea acestui capitol este o prezentare generală a platformei Mozilla, arhitectura acestei platforme și câteva noțiuni despre tehnologiile folosite și cum pot fi acestea utilizate în dezvoltarea de aplicații.
Capitolul 2 este dedicat proiectării sistemului și începe cu formularea cerințelor și prezentarea arhitecturii generale a sistemului. Se identifică componentele sistemului și se prezintă rolul acestora. Urmează proiectarea fiecărei componente și prezentarea interfețelor lor, proiectarea și verificarea protocoalele de securitate.
Capitolul 3 conține implementarea sistemului și descrierea fiecărei componente cu ajutorul diagramelor de clase corespunzătoare și a diagramelor de stare ale principalelor clase.
În final sunt prezentate și explicate măsurări ale performanței sistemului, și concluziile referitoare la sistemul prezentat.
1. STUDIU ASUPRA METODELOR MODERNE DE AUTENTIFICARE, AUTORIZARE ȘI ACONTROL ALA ACCESULUI
1.1 Noțiuni generale ale Criptografiei
Criptografia reprezintă o ramură a matematicii care se ocupă cu securizarea informației precum și cu autentificarea și restricționarea accesului într-un sistem informatic. În realizarea acestora se utilizează atât metode matematice (profitând, de exemplu, de dificultatea factorizării numerelor foarte mari), cât și metode de criptarea cuantică. Criptologia este considerată ca fiind cu adevărat o știință de foarte puțin timp. Aceasta cuprinde atât criptografia – scrierea secretizată – cât și criptanaliza. Criptarea se împarte în doua mari categorii: criptarea simetrică si cea asimetrică.
Înainte de epoca modernă, criptografia se ocupa doar cu asigurarea confidențialității mesajelor (criptare) – conversia de mesaje dintr-o formă comprehensibilă într-una incomprehensibilă, și inversul acestui proces, pentru a face mesajul imposibil de înțeles pentru cei care interceptează mesajul și nu au cunoștințe secrete adiționale (anume cheia necesară pentru decriptarea mesajului). În ultimele decenii, domeniul s-a extins dincolo de problemele de confidențialitate și include, printre altele, și tehnici de verificare a integrității mesajului, autentificare a emițătorului și receptorului, semnătură electronică, calcule securizate.
Criptografia, folosită intr-un protocol de securitate, dorește să asigure următoarele deziderate fundamentale pentru securitatea informației: confidențialitate, integritatea datelor, autenticitatea și ne-repudierea.
1.1.1 Criptografia simetrică
Criptografia cu chei simetrice se referă la metode de criptare în care atât trimițătorul cât și receptorul folosesc aceeași cheie (sau, mai rar, în care cheile sunt diferite, dar într-o relație ce la face ușor calculabile una din cealaltă). Acest tip de criptare a fost singurul cunoscut publicului larg până în 1976 [18, 28]. Problema fundamentală a utilizării criptografiei în rețele este aceea a găsirii unor modalități de distribuție sigură și periodică a cheilor criptografice, fiind necesar ca acestea să fie schimbate cât mai des. Uzual, se folosește un protocol de schimbare de chei între participanți, sau criptografia cu chei publice. Fiindcă securitatea criptării simetrice depinde mult de protecția cheii criptografice, administrarea acestora este un factor esențial și se referă la [25]:
generarea cheilor, adică mijloacele (pseudo)aleatoare de creare a succesiunii de octeți (biți) ai cheii;
distribuția cheilor, adică modul în care se transmit și se fac cunoscute cheile tuturor utilizatorilor cu drept de acces la informațiile criptate;
memorarea cheilor, adică stocarea lor sigură pe un suport magnetic sau pe un card, de obicei criptate sub o altă cheie de cifrare a cheilor, numită și cheie master.
Algoritmii de criptare cu chei simetrice (cele mai populare includ: Twofish, Serpent, AES (Rijndael), Blowfish, CAST5, RC4, TDES, IDEA) [18, 25] se pot împărți în două categorii: cifru pe blocuri și cifru pe flux. Cel mai celebru cifru simetric pe blocuri, DES (Data Encryption Standard) are deja peste 20 de ani. El este primul standard dedicat protecției criptografice a datelor de calculator. Progresele tehnologice au impus înlocuirea DES-ului care a devenit vulnerabil. S-a demonstrat de curând că, folosind o mașină paralelă complexă, se poate găsi, într-un timp de aproximativ 60 de ore, o cheie de 56 de biți cu care a fost criptat un bloc de text clar. Din acest motiv, în 2000, organizația guvernamentală americană NIST (National Institute of Standards and Technology) a selectat algoritmul Rijndael (AES) [5], dezvoltat de doi criptografi belgieni, Joan Daemen și Vincent Rijmen, să fie noul standard în criptografie simetrică.
1.1.2 Criptografia asimetrică
Criptografia asimetrică, sau criptografie cu chei publice, este un tip de criptografie în care utilizatorul are o pereche de chei, una publică și una privată, dependente una de cealaltă, dar aproape imposibil de calculat una din ele dacă se cunoștea cealaltă. Astfel, una dintre chei se poate face publică și stocată în domeniul public iar cealaltă va fi cheia privată, cunoscută numai de către posesor. Folosind cheia publică se poate cripta un mesaj care nu va putea fi decriptat decât cu cheia pereche, cea privată. O analogie foarte potrivită pentru proces este folosirea cutiei poștale. Oricine poate pune în cutia poștală a cuiva un plic, dar la plic nu are acces decât posesorul cheii de la cutia poștală. Dacă mesajul a fost criptat cu cheia privată, se poate decripta de oricine cu cheia publică. Acesta se numește semnătură digitală, pentru că se cunoaște destinatarul mesajului (având în posesie cheia secretă pentru a genera mesajul), și se poate dovedi că mesajul este nemodificat, precum arată și Fig. 1. O analogie pentru semnăturile digitale ar fi sigilarea unui plic folosind un sigiliu personal. Plicul poate fi deschis de oricine, dar sigiliul personal este cel care verifică autenticitatea plicului. Matematic, cele două chei sunt legate, însă practic nu se pot deriva una din cealaltă [18]. Avantajul evident constă în faptul că cheia secretă este cunoscută doar de o singură entitate, și nu trebuie trimisă niciodată, fiind astfel aproape imposibil de atacat cu succes, în cazul în care este folosit corect.
O problemă pentru criptografia asimetrică este dovedirea autenticității cheii publice, trebuie dovedit că nu a fost înlocuită de o a treia persoană malițioasă. O abordare comună este folosirea unei infrastructuri pentru chei publice (PKI – Public Key Infrastructure [25]), în interiorul căreia, una sau multe „third-parties”, cunoscute sub numele de autorități de certificare (CA – Certification Autority), certifică posesorul perechii de chei. O altă abordare, folosită de PGP (Prety Good Privacy), un program care garantează securitate criptografică și autentificare, este metoda „web of trust” pentru a asigura autenticitatea perechii de chei, o metodă descentralizată prin care orice utilizator, prin intermediul unui certificat de identitate, poate garanta autenticitatea.
Criptosistemul RSA este unul dintre cei mai cunoscuți algoritmi criptografici cu chei publice, și este de asemenea primul algoritm utilizat atât pentru criptare, cât și pentru semnătura electronică [28]. Algoritmul a fost dezvoltat în 1977 și publicat în 1978 de Ron Rivest, Adi Shamir și Leonard Adleman la MIT și își trage numele de la inițialele numelor celor trei autori. Algoritmul implică trei stări: generarea cheilor, criptarea și decriptarea. În acest moment, cea mai eficientă metodă de a realiza aceasta este descompunerea în factori primi a lui n, iar acesta înseamnă un nivel de dificultate similar cu problema factorizării. Cel mai mare număr factorizat vreodată avea 663 biți, iar cheile folosite de obicei au o lungime de 1024 sau 2048 biți, ceea ce demonstrează siguranța acestui algoritm. Perechea de chei se generează după următorii pași:
Se generează două numere prime, de preferat mari, p și q;
Se calculează n=pq și Ф=(n–1)(q–1);
Se alege un întreg aleator e, 1 < e < φ, astfel încât cmmdc(e, φ) = 1. Perechea (n, e) este cheia publică.
Folosind algoritmul lui Euclid extins, se calculează întregul d, unicul cu proprietatea că constituie cheia secretă.
În general, deoarece se bazează pe o operație destul de costisitoare din punct de vedere al timpului de calcul și al resurselor folosite, și anume exponențierea modulo n, viteza RSA este mult mai mică decât a algoritmilor de criptare cu cheie secretă. De aceea, în sistemele de comunicație în timp real, în care viteza de criptare și decriptare este esențială (cum ar fi, de exemplu, aplicațiile de streaming video sau audio securizate), se folosește un sistem de criptare hibridă, adică RSA se folosește doar la începutul comunicației, pentru a transmite cheia secretă de comunicație, care ulterior este folosită într-un algoritm cu cheie secretă, cum ar fi 3DES sau AES.
1.1.3 Funcții hash
Se poate numi o funcție hash (message digest) orice procedură bine definită sau o funcție matematică care convertește o cantitate mare de date (de dimensiuni variabile) într-un alt set de date, de obicei mult mai redus ca dimensiune, și de lungime fixă [18]. Funcția este ireversibilă, iar aceleași date de intrare va avea ca rezultat aceleași date de ieșire daca se aplică aceeași funcție hash pe ele. Pentru hash-urile bune, coliziunile(două texte clare diferite care produc același hash) sunt extrem de dificil de găsit. Funcțiile hash sunt folosite în mai multe domenii, de exemplu pentru a accelera căutările în tabele, sau baze de date mari, ca sume de control, coduri de corectoare de erori, sau în criptografie, componente în schemele de semnătură digitală. Cele mai des folosite funcții hash in criptografie sunt MD5 (Message Digest Algorithm 5) și SHA1 (Secure Hash Algorithm), cea din urmă fiind mai sigură. Putem vedea rezultatul celor două funcții menționate aplicate pentru textul „Hello World” în Tabelul 1.
Tabel 1. Rezultatele funcțiilor hash MD5 și SHA1
1.2 Protocoale de securitate
Protocoalele de securitate sunt o secvență de operațiuni ce folosesc transformări criptografice și al căror principal scop este să asigure o serie de proprietăți de securitate, cum ar fi: autentificarea, integritatea, secretizarea, ne-repudierea. Proiectarea unui protocol corect este dificil, pentru că nu se pot verifica cu ușurință. Multe dintre protocoale de securitate propuse s-au dovedit mai târziu a avea defecte, de exemplu protocolul cu cheie simetrică Needham-Schroeder a fost dovedit defect de către Burrows, Abadi și Needham [4], la 3 ani după publicare. În cazul descoperirii defectelor abia după ce protocoalele au devenit utilizate pe scară largă consecințele pot fi foarte grave, și acest fapt a determinat multe persoane să fie sceptice referitor la protocoalele de securitate în general. Există câteva tehnici de formale pentru analiza și verificarea protocoalelor de securitate. Printre acestea se numără: BAN Logic, NRL Analzyer, FDR, Spi calculus, metoda inductivă, teoria spațiilor Strand. Corectitudinea protocoalelor poate fi verificată parțial cu aceste metode.
O altă problemă în ceea ce privește proiectarea și verificarea protocoalelor de securitate este dificultatea de a specifica criteriile de corectitudine sau obiectivele protocolului [9]. Multe protocoale sunt proiectate greșit pentru că proiectanții lor nu știu exact ce obiective vor să atingă. Specificând cerințele protocoalelor se clarifică problema pe care trebuie să o rezolve proiectanții și realizează o legătură între criteriile informale legate de corectitudine și descrierea formală a protocolului. Totuși încă nu există o definire precisă a proprietăților necesare unui protocol, la fel cum nu există o noțiune exactă a ceea ce înseamnă autentificarea.
Proiectarea protocoalelor de securitate este un proces repetat de proiectare și verificare. Datorită anilor de cercetare în verificarea protocoalelor, analiza și verificarea a devenit mult mai ușoară, cu toate acestea procesul depinde de reguli și experiența proiectantului. Încă nu există o metodologie de proiectare.
1.2.1 Principii de proiectare
Protocoalele de securitate, cum sunt cele folosite pentru autentificare, sunt predispuse la greșeli de proiectare de multe tipuri. De-a lungul timpului, au fost propuse multe formalisme pentru a investiga și analiza protocoalele cu scopul de a vedea dacă au defecte. Deși uneori aceste formalisme s-au dovedit utile, acestea nu sugerează reguli de proiectare, nu sunt în mod direct utile pentru prevenirea defectelor.
În [4, 11] sunt prezentate principiile proiectării protocoalelor de securitate. Aceste principii nu sunt necesare pentru a asigura corectitudinea, dar nu sunt nici suficiente. Ele sunt utile pentru că folosirea lor simplifică protocoalele și previne repetarea unor confuzii și greșeli deja descoperite și publicate. Principiile sunt formulate pentru a evita anumite aspecte ale protocoalelor care sunt greu de analizat. Dacă aceste aspecte sunt evitate, devine mai puțin necesar să se recurgă la folosirea metodelor formale. Principiile sunt indicații informale și sunt utile independent de orice logică.
Un protocol este un set de reguli sau convenții care definesc un schimb de mesaje între doi sau mai mulți parteneri. Acești parteneri sunt persoane, procese sau calculatoare, care vor fi numiți în continuare interlocutori. Într-un protocol de securitate toate sau o parte din mesaje sunt criptate în întregime sau parțial. În acest context criptarea și decriptarea sunt definite ca fiind transformări dependente de cheie ale unor mesaje care pot fi inversate doar prin folosirea unei chei stabilite. Aceste chei pentru criptare și decriptare sunt aceleași sau pot fi diferite în funcție de algoritmul de criptare folosit.
În continuare sunt prezentate aceste principii pentru proiectarea protocoalelor de securitate. Sunt prezentate două principii de bază, primul fiind preocupat de conținutul mesajului, iar al 2-lea este preocupat de circumstanțele în care un mesaj se comportă corect [27]:
Fiecare mesaj ar trebui să specifice ce înseamnă, ce conține, interpretarea lui ar trebui să depindă doar de conținutul său. Ar trebui să se poată scrie o propoziție care să descrie conținutul mesajului.
Condițiile în care un mesaj se comportă conform așteptărilor ar trebui specificate clar pentru ca oricine modifică un protocol să vadă dacă acestea sunt acceptabile sau nu.
Pentru o bună înțelegere a primului principiu luăm un exemplu: un server de autentificare S trimite un mesaj a cărui sens poate fi exprimat astfel: „După recepționarea unei secvențe de biți P, S trimite lui A o cheie de sesiune K pentru a fi folosită în conversația cu B”. Toate elementele trebuie reprezentate în mesaj pentru ca înțelesul său să poată fi refăcut de destinatar fără a fi nevoie de informații din context. Pentru exemplu dat, dacă P, S, A, B sau K sunt omise din mesaj și se dorește obținerea lor din context, există posibilitatea ca un mesaj să poată fi folosit în locul altui mesaj, cu scopul de a înșela.
Principiul doi menționează că nu este suficient ca mesajul să fie înțeles pentru a se comporta corect, trebuie să îndeplinească o varietate de alte condiții. Aceste condiții de cele mai multe ori constau în ce poate fi privit informal ca o declarație de încredere. Declarațiile de încredere nu pot fi greșit concepute, doar pot fi luate în considerare nepotrivit. De exemplu, dacă cineva consideră că alegerea cheilor de sesiune ar trebui făcută de un server de încredere și nu de un participant la sesiune, atunci el nu va dori să folosească un protocol cum este Wide-mouthed-frog (protocol care distribuie o cheie de sesiune generata de unul din interlocutori prin intermediul unui server ).
Pornind de la aceste doua principii au fost formulate alte principii mai specifice.
Principiul 3 este un caz particular al principiului1: dacă identitatea unui interlocutor este esențiala pentru sensul mesajului, este prudent să se menționeze numele său explicit în mesaj. Numele relevante pentru un mesaj pot fi uneori deduse din alte date și din ce cheie de criptare s-a folosit. Când această informație nu poate fi dedusă, omiterea ei din mesaj poate avea consecințe grave.
În continuare sunt prezentate notațiile folosite în exprimarea celorlalte protocoale: K – cheia de criptare publică în criptarea asimetrică, și cheia de criptare/decriptare în criptarea simetrică
K–1 – cheia privată în criptarea asimetrică
A, B, C, S – interlocutori ( Sfiind serverul )
{X}K – mesajul X este criptat cu cheia K și oricine cunoaște inversa lui K (este K în criptarea simetrică și K–1 în cea asimetrică) poate decripta mesajul, iar dacă K este secret putem vedea {X}K ca un mesaj semnat digital.
Criptarea poate fi folosită pentru diferite scopuri:
pentru asigurarea confidențialității. În acest caz când un interlocutor cunoaște K–1 și vede {X}K știe că acest mesaj este pentru cineva care cunoaște K–1 și va poate deduce că îi este adresat cu ajutorul informațiilor adiționale din mesaj.
este uneori folosită pentru garantarea autenticității. În acest caz este de presupus că doar emițătorul corect cunoaște cheia secretă pentru a cripta mesajul. Criptarea contribuie clar la sensul general al mesajului.
contribuie la unirea părților de mesaje: recepționarea {X}K și {Y}K nu este întotdeauna același lucru cu recepționarea {X}K și {Y}K. Dacă criptarea este folosită doar pentru unirea părților de mesaje este suficientă semnătura digitala. Modul de unire a mesajelor este dependent de protocol și este de multe ori subtil.
generarea de numere aleatoare cu ajutorul funcțiilor „one-way”.
Principiul 4 este legat de folosirea criptării: trebuie să se specifice clar de ce se folosește criptarea. Criptarea nu este sinonimă cu securitatea, și folosirea ei improprie poate conduce la erori. Criptarea nu este ieftină, și dacă nu se știe de ce este folosită poate conduce la redundanță.
Principiul 5 este legat de semnarea datelor criptate: când un interlocutor semnează un material care a fost deja criptat nu trebuie presupus că acesta cunoaște conținutul mesajului. Pe de altă parte, este corect să presupui că interlocutorul care semnează un mesaj și apoi îl criptează pentru secretizare cunoaște conținutul mesajului.
O parte importantă în sensul mesajului este formată din informațiile temporale. O precondiție comună pentru a prelucra un mesaj este că există un motiv care te face să crezi că mesajul este recent, și nu un răspuns al unui mesaj mai vechi. Această noutate a mesajului trebuie să fie indusă de o componentă a mesajului. Această componentă trebuie să fie legată de restul mesajului pentru a nu putea fi atașată unui mesaj mai vechi.
Principiul 6: Scopul folosirii nonce-urilor (număr generat aleatoriu) trebuie bine precizat, fie pentru asociere, fie pentru succesiunea temporală. Ceea ce poate asigura succesiunea temporală poate afecta asigurarea asocierii, și poate asocierea este mai bine stabilită prin alte mijloace.
Principiul 7: valorile (nonce-urile) predictibile (cum este valoarea unui contor) pot fi folosite pentru garantarea noutății în cadrul unui protocol întrebare-răspuns („challengeresponse”), dar pentru ca această cantitate predictibilă să fie eficientă trebuie protejată pentru ca un intrus să nu poată simula o întrebare și mai târziu să trimită un răspuns.
Principiul 8: Dacă timestamps (marca de timp) sunt folosite pentru a garanta noutatea prin referire la timpul absolut, atunci diferența dintre ora locală a diferitelor mașini trebuie să fie mult mai mică decât durata de viață permisă a unui mesaj pentru a fi considerat valid.
Principiul 9: o cheie se poate să fi fost folosită recent, pentru criptarea unui nonce de exemplu, și totuși să fie destul de veche și posibil compromisă. Folosirea recentă nu face ca cheia să pară mai sigură decât nefolosirea ei recent.
Principiul 10: dacă o codare este folosită pentru a prezenta sensul unui mesaj, atunci ar trebui să fie posibil să spui ce codare este folosită. În cazurile comune unde codarea este dependentă de protocol, ar trebui să fie posibil să se deducă că mesajul aparține acelui protocol, și mai exact aparține unei rulări particulare a protocolului, și să se afle numărul mesajului în acest protocol.
Principiul 11: proiectantul protocolului ar trebui să știe care sunt relațiile de încredere de care depinde protocolul său și de ce sunt necesare aceste dependențe. Motivele pentru care o relație particulară de încredere să fie acceptabilă ar trebui explicit bazate pe judecată și politici decât pe logică.
1.2.2 Proiectare via teste de autentificare
Proiectarea protocoalelor de securitate, descrisă în [4] urmărește următoarele obiective, între doi participanți P și Q [14, 15]:
Confidențialitate: se definește ca fiind protecția datelor trimise în fata persoanelor neautorizate.
Autenticitatea I: două entități aflate într-un schimb de mesaje să se poată identifica una pe cealaltă. În prima fază, la inițierea conexiunii, acest serviciu asigură ca cele două entități sunt autentice. În al doilea rând, autenticitatea presupune că transferul de date între cele două entități să nu fie interferat astfel încât o a treia entitate să se legitimeze ca fiind una din ele. Fiecare participant P trebuie să aibă garanțe că fiecare partener Q a primit și a acceptat datele lui P.
Non-repudierea: previne situația în care o entitate refuza să recunoască acțiuni anterioare. Când un mesaj este trimis, destinatarul poate demonstra ca mesajul primit este cel trimis de emițător. Fiecare participant P trebuie să-și dovedească autenticitatea I, garantat de o terță parte.
Autenticitatea II: Fiecare participant Q trebuie să aibă garanție ca un mesaj având ca expeditor P, a fost creat într-adevăr de partenerul P, într-o rulare recentă a acestui protocol.
Să presupunem o entitate într-un protocol criptografic ca fiind creatorul și transmițătorul unui mesaj care conține o valoare nouă v, iar mai târziu primind un mesaj conținând valoarea v, dar într-un alt context criptografic. De aici poate conclude că o altă entitate, având în posesie cheia relevantă K a recepționat și a transformat mesajul care conținea valoarea v. Dacă cheia K este secretă, această entitate nu poate fi penetratorul, deci trebuie să fie un participant reglementar. Testele de autentificare oferă suficiente condiții ca să putem dovedi că aceste schimbări a formei criptografice sunt acțiunile unui participant regular. Putem deosebi două tipuri de teste de autentificare:
Teste de ieșire: o valoare unică a poate fi transmisă numai în formă criptată {|…a…|}K, unde cheia K este secretă. Dacă mai târziu un mesaj primit conține valoarea a în afara contextului {|…a…|}K, înseamnă că un participant regular a fost responsabil de transformarea {|…a…|}K →…a… . Este un test de ieșire pentru că elementul criptat iasă.
Teste de intrare: dacă, în schimb, a este primit într-o formă criptată {|…a…|}K dar nu a fost trimis în acest context, și cheia K este secretă, atunci putem afirma din nou că transformarea nu a fost efectuată de un penetrator. Testul care conține transformarea …a… → {|…a…|}K este o un test de intrare pentru că elementul criptat intră.
Dacă o valoare unică a este transmisa intr-o formă criptată {|h|}K, și primită înapoi într-o altă formă criptată {|h′|}K′, iar cheile K–1 și K′ sunt secrete, atunci este un test și de intrare, și de ieșire.
1.2.3 Independența protocoalelor de securitate
Dacă este de așteptat ca două sau mai multe protocoale de securitate să ruleze în paralel trebuie să se determine dacă un protocol afectează securitatea celorlalte protocoale. Acest lucru se realizează analizând independența protocoalelor implicate. Când mai multe protocoale de securitate rulează combinate pentru intrușii apar noi oportunități pentru a obține mesajele. Această combinare de protocoale s-a dovedit o cauză semnificativă a eșuării protocoalelor și face mult mai dificilă analiza protocoalelor. A fost dovedită o problemă în aplicarea metodelor formale protocoalelor de securitate.
Un protocol, numit protocol primar, este independent de alte protocoale, numite protocoale secundare, dacă protocolul primar își îndeplinește scopul de securitate fără a depinde dacă un protocol secundar rulează în același timp. Pentru dovedirea independenței protocoalelor au fost folosite spațiile strand. Un strand este o secvență de mesaje transmise și recepționate. Protocoalele de securitate sunt modelate cu ajutorul acestor spații strand. În [11] este propusă reprezentarea protocoalelor de securitate folosind un model canonic care permite realizarea unei analize sintactice pentru determinarea independenței protocoalelor. Construirea mesajelor după modelul propus este realizată prin înlocuirea fiecărei componente a mesajului din specificarea obișnuită cu un tip. În modelul canonic propus, mesajele schimbate de participanți sunt reprezentate sub forma unor construcții sintactice, evidențiind structura mesajelor care influențează direct independența protocoalelor. Bazându-se pe cunoștințele fiecărui participant se modelează viziunea fiecărui participant asupra aceluiași mesaj. Primul pas este îmbunătățirea specificațiilor obișnuite folosind cunoștințele participanților pentru a se observa clar care sunt componentele mesajului care pot fi validate de participanți. Pornind de la această reprezentare este construit un model canonic, numit model de tipuri, care înlocuiește componentele mesajelor cu tipul lor corespunzător, reprezentându-se astfel explicit structura mesajului. Această reprezentare permite realizarea analizei sintactice pentru determinarea independenței protocoalelor.
Tipurile componentelor mesajelor sunt:
Kt: cheie,
r: rol,
n: nonce,
i: index, de exemplu o secvență de numere sau o marcă de timp,
u: tip necunoscut,
mt: numele protocolului de securitate.
1.3 Infrastructura Cheilor Publice (PKI)
Infrastructurile cu chei publice (Public Key Infrastructure / PKI) nu este o tehnologie relativ nouă, ea se bazează pe criptografia asimetrică și oferă diverse servicii în încercarea de a rezolva diverse probleme de securitate. PKI este o combinație de produse hardware și software, politici și proceduri care asigură securitatea de bază necesară astfel încât doi utilizatori, care nu se cunosc sau se află în puncte diferite de pe glob, să poată comunica în siguranță. La baza PKI se află certificatele digitale, un fel de pașapoarte electronice ce mapează semnătura digitală a utilizatorului la cheia publică a acestuia. O infrastructură cu chei publice reprezintă cadrul și serviciile ce pun la dispoziția utilizatorului metode pentru a genera, distribui, controla, contoriza și revoca certificate cu chei publice. O structură PKI se constituie, de obicei, din una sau mai multe autorități de certificare (CA), un container cu certificate, și documentația ce include politica de certificare [10]. Într-un sens mai larg, se poate spune că PKI integrează certificatele digitale, criptografia cu cheie publică și noțiunea de autoritate de certificare într-o arhitectură de securitate a rețelei.
1.3.1 Certificatele X.509
Certificatele identifică persoana specificată în certificat și asociază acelei persoane o anumită pereche de chei publică/privată. Certificatul X.509 a fost folosit prima dată în 1988, și este un standard ITU-T (International Telecommunication Union) pentru Infrastructura Cheilor Publice (Public Key Infrastructure/PKI) [10]. Certificatele de obicei sunt emise de autorități de certificate (certificate authorities / CA), și conțin următoarele informații: versiunea certificatului, un număr de serie, identificator de algoritm, numele emitentului, perioada de valabilitate a certificatului, numele posesorului, algoritmul cheii publice, cheia publică și câteva câmpuri opționale. În afară de aceste informații predefinite, certificatele X.509 v3 suportă și date personalizate, unde voi stoca drepturile de acces pentru fiecare utilizator separat. Certificatele sunt relativ ușor de generat, iar datorită dimensiunii mici, și fiind stocate in format .PEM (Privacy Enhanced Mail), codificat BASE64, transmisia lor se realizează fără probleme. Un dezavantaj constituie faptul că suportăun singur algoritm de criptare la un moment dat.
Un exemplu de certificat X.509 v3, emis de către Thawte, pentru Google Mail este prezentat în Fig. 2.
1.4 Mecanismul Single Sign-On (SSO)
Utilizatorii de rețea folosesc un set de informații pentru identificare, de obicei numele de utilizator și parola, pentru fiecare furnizor de servicii (Service Provider/SP) la care sunt înregistrați. În cadrul acestei lucrări, un furnizor de servicii este o entitate care oferă anumite resurse sau informații utilizatorilor, de exemplu servicii de web, servicii de mesaje, site-uri web/FTP sau orice fel de format de flux. Numărul acestor furnizori de servicii a crescut enorm, și a ajuns la un punct unde utilizatorii rețin cu greu informațiile necesare pentru identificare. Cea mai simplă și răspândită soluție este de a folosi aceeași parolă la fiecare furnizor la care sunt înregistrați – un compromis între securitate și ușurința de folosire. O soluție a acestei probleme de securitate ar fi implementarea unui mecanism Single Sign-On (SSO) [8]. SSO este o proprietate de control de acces a sistemelor software multiple, legate, dar independente. Cu această proprietate, utilizatorul se autentifică doar o singură dată, iar identificarea se face de către sistem, de câte ori va fi nevoie, la fiecare furnizor din rețea. Această autentificare este automată, nu necesită intervenția utilizatorului . Beneficiile unui sistem SSO includ [22]:
Scade numărul parolelor folosite, îmbunătățind semnificativ securitatea sistemelor;
Se reduce din timpul folosit reintroducând parole pentru aceeași identitate;
Securitate la toate nivelele de intrare/ieșire/accesare a sistemelor.
Există mai multe modalități de a crea un sistem SSO, de exemplu: protocolul de autentificare Kerberos interoghează utilizatorul pentru datele de identificare, și emite un tichet (Ticket granting gicket/TGT), care va fi folosit pentru autentificare în continuare. Câteva dezavantaje a acestui sistem includ arhitectura centralizată, care constă în serverul principal care trebuie să fie funcțional pentru a permite autentificarea utilizatorilor. Acest server central stochează datele tuturor utilizatorilor, fiind astfel ținta eventualelor atacuri la adresa sistemului. Kerberos necesită sincronizarea ceasurilor pe diferite servere, tichetele emise de server au o perioadă de valabilitate, de obicei 10 minute, iar dacă ceasul furnizorului nu este sincronizat cu cel al serverului care a emis tichetul, autentificarea eșuează. Un alt sistem SSO folosește smart-carduri pentru a stoca informații despre posesor, și pentru autentificarea utilizatorilor. Acest card, fabricat de obicei din plastic, conține un circuit integrat, capabil de a prelucra anumite date. Smart cardurile sunt răspândite, și foarte utile în anumite domenii, dar necesitatea acestui hardware îl face greu de utilizat în cazul nostru. Încă câteva sisteme SSO de menționat ar fi cel bazat pe parole de unică folosință (One-time passwords/OTP) sau Integrated Windows Authentication (IWA), introdus cu Windows 2000 [30]. Pentru modelul meu am ales să folosesc autentificarea pe baza certificatelor client X.509, descris în secțiunea 2.3.1.
1.5 Ingineria programării bazată pe componente (CBSE)
Componentele software sunt unități binare produse, dezvoltate și achiziționate independent care interacționează pentru a forma un sistem funcțional. Este esențial să fie dezvoltate independent și sub formă binară pentru a permite integrarea lor într-un produs indiferent de identitatea producătorilor și pentru a putea fi integrate robust în sistem. Construirea unor aplicații noi prin combinarea componentelor achiziționate din exterior și a celor dezvoltate în interior îmbunătățește calitatea produsului și scurtează perioada de dezvoltare, produsul ajungând pe piață mult mai repede. În același timp adaptarea aplicației la noi cerințe poate fi făcută doar asupra componentelor care necesită acest lucru fără a fi nevoie să se lanseze o noua versiune a aplicației.
1.5.1 Application Programming Interface (API)
O interfață API este un set de funcții, structuri de date, clase de obiecte și/sau protocoale accesibile din librării, sau oferite de serviciile sistemului de operare, pentru a suporta crearea aplicațiilor. Un program care oferă funcționalitatea descrisă de interfața API este implementarea interfeței API. Interfața API în sine este abstractă, în sensul că specifică instanța dar nu se implică în detalii de implementare. Un API poate fi dependent de un limbaj, dar și independent, adică poate fi folosit din mai multe limbaje de programare. Standardul POSIX (Portable Operating System Interface for Unix) definește un API care permite scrierea unor game mari de funcții de bază în așa fel încât să fie compatibile cu mai multe sisteme de operare. Câteva API-uri populare includ: ASPI pentru interfața SCSI, DirectX pentru Microsoft Windows, OpenGL cross-platform 3D, Carbon și Cocoa pentru Macintosh, etc.
Câteva principii de bază în proiectarea unui API: să facă un singur lucru, dar să-l facă bine – funcționalitatea să fie ușor de explicat. Să fie cât se poate de mic, dar să-și satisfacă cerințele – poți să adăugi mai târziu, dar e mai greu să scoți. Implementarea nu ar trebui să influențeze API-ul. Un aspect important, și un scop important al fiecărui API este să ascundă informațiile irelevante, clasele și membrii ar trebui să fie privați, cât posibil. Numele membrilor publici să fie sugestive, dar API-ul să aibă o documentație detaliată. În general să fie ușor de învățat, ușor de folosit chiar și fără documentație, greu de folosit incorect.
1.6 Platforma Mozilla
Mozilla este o platformă portabilă, gratuită, open-source creată în totalitate cu ajutorul componentelor software. Mozilla a luat naștere în 1998 prin decizia companiei Netscape de a publica sursele browserului Netscape și declararea lor ca open-source permițând contribuția programatorilor din toată lumea pentru a îmbunătăți browserul. Cu timpul platforma Mozilla a devenit dintr-o aplicație browser foarte mare, o platformă mare portabilă pe care un set de aplicații mai mici sunt construite și rulează. Ea oferă fundația pe care programatorii pot să dezvolte ușor aplicații de nivel înalt fără a mai irosi timp prețios implementând funcționalități de bază, oferite acum de platformă.
Cel mai important avantaj al aplicațiilor dezvoltate pe platforma Mozilla este portabilitatea pe majoritatea sistemelor de operare, programele vor avea aceeași structură indiferent dacă vor rula pe Windows, Unix sau Mac. Acest lucru e posibil pentru că Mozilla se comportă ca un nivel de interpretare între aplicație si sistem de operare. Portabilitatea este realizată cu ajutorul XPFE (Extreme Portability Front End), o tehnologie dezvoltată pentru a economisi timp datorită dezvoltării open-source și care s-a dovedit o inovație.
XPFE folosește o serie de standarde web existente cum ar fi Cascading Style Sheets (CSS) (un limbaj cu ajutorul căruia se creează aspectul grafic al aplicației), XUL (un dialect al limbajului XML utilizat pentru descrierea interfețelor grafice), JavaScript (un limbaj pentru script-uri cu o sintaxă asemănătoare cu cea a limbajului C), RDF (un dialect al XML utilizat pentru salvarea datelor) și XPCOM [19] (un sistem pentru descoperirea și administrarea obiectelor care permite JavaScript sau oricărui limbaj pentru script-uri să acceseze librăriile C și C++). Dezvoltarea de aplicații se realizează folosind aceste tehnologii combinate cu limbaje de programare cum ar fi C, C++, Python și Interface Definition Language (IDL).
1.6.1 Arhitectura Mozilla
În Fig. 3 este prezentată arhitectura simplificată a platformei Mozilla. Se observă o așezare pe nivele semi-independente. Legătura dintre sistemul de operare și platformă se realizează la nivelurile inferioare prin intermediul unei interfețe, accesul la serviciile oferite de acesta făcându-se în trei moduri: printr-un API (Application Programming Interface) portabil numit NSPR (Netscape Portable Runtime), prin cod Java interpretat de JVM (Java Virtual Machine) sau prin implementarea unor plugin-uri. Pentru o flexibilitate și o deschidere mai mare a sistemului funcționalitatea nivelelor inferioare este înglobată în mai multe componente independente, administrarea lor fiind realizată de un sistem de mediere portabil numit XPCOM (Cross Platform Component Object Model). Componente XPCOM [19] pot fi dezvoltate în C, C++, JavaScript, Python sau alte limbaje pentru care exista legături speciale create. Portabilitatea tehnologiilor folosite în aceste nivele inferioare conduce la o portabilitate crescută a întregii platforme și implicit a tuturor aplicațiilor dezvoltate pe ea. În momentul de față Mozilla este disponibilă pe principalele trei sisteme de operare existente pe piață: Microsoft Windows, Linux și Mac OS.
Aplicațiile care vor sa obțină acces la componentele XPCOM folosesc tehnologia XPConnect care asigură accesul limbajelor pentru script-uri (cum este JavaScript) la interfețele componentelor de la nivelele inferioare. Legătura funcționează și în sens invers permițând interacțiunea unor obiecte implementate în JavaScript cu alte obiecte implementate de obicei în limbaje de programare clasice cum ar fi C sau C++.
Platforma Mozilla, pentru a oferii portabilitate, descrie interfețele componentelor utilizând un limbaj independent de platformă numit XPIDL (Cross Platform Interface Definition Language, o variantă a limbajului IDL utilizat de sistemul de administrare a obiectelor CORBA). De asemenea se pot accesa servicii cum este NSS ( Netscape Secure Services ) un serviciu de securitate care printre alte facilitați oferă posibilatea de utilizare a certificatelor digitale.
Pentru a obține acces la interfața componentelor se folosește JavaScript care utilizează tehnologia XPConnect, menționat anterior. Interfața cu utilizatorul este implementată sub forma unor documente scrise în XUL (limbajul derivat din XML specific platformei) sau mult mai cunoscutul limbaj HTML, acestea se pot combina cu CSS ( Cascade Sheet Style), eXtensible Binding Language (XBL), DTD ( Document Type Definition ) pentru a oferi un caracter internațional.
Platforma pune la dispoziția programatorilor un format portabil pentru salvarea datelor
numit RDF ( Resource Description Framework ) care este o particularizare a limbajului XML.
1.6.2 XPCOM
XPCOM (Cross Platform Component Object Model) reprezintă principala inovație oferită de platforma Mozilla [19]. Aceasta este principalul motiv pentru care Mozilla este cu adevărat o platforma de dezvoltare. XPCOM este tehnologia prin care platforma Mozilla își administrează propriile componente sau pe cele implementate de alte aplicații, de asemenea se ocupa de regăsirea și instanțierea în timpul rulării a diverselor componente.
Flexibilitatea ridicată a platformei a fost obținută prin organizarea codului sub forma componentelor XPCOM independente accesibile printr-un set de interfețe pe care le implementează. Această abordare facilitează adăugarea de funcționalități noi la momente ulterioare cu eforturi și costuri minime cu condiția ca toate componentele să implementeze un set de interfețe standard care să poată face posibilă comunicarea dintre ele.
Atât componentele cât și interfețele sunt identificate printr-un UUID (Universally Unique Identifier, un număr pe 128 de biți) sau printr-un identificator specific platformei numit ContractID, o secvență de caractere într-o formă ușor de reținut de utilizatori. Majoritatea componentelor XPCOM sunt scrise în C sau C++ cu NSPR la bază, dar dacă interfețele lor utilizează exclusiv tipuri de date definite de XPIDL ele pot fi accesate ușor de limbaje ca JavaScript prin intermediul tehnologiei XPConnect. JavaScript este de obicei limbajul care asigură legătura dintre interfața cu utilizatorul și componentele de la baza platformei.
1.7. Concluzii la compartimentul 1
Criptografia și laturile conexe criptografiei reprezintă un important complex de instrumente care permit să planificăm și să implementăm un mecanism sigur de autentificare, autorizare, dar și de control al accesului în sistemele distribuite.
Acest lucru este unul foarte important anume în astfel de sisteme care pot reprezintă ramificații de sute de filiale în întreaga lume iar fiecare filială are un server care stochează datele locale și tratează tranzacțiile locale. Fiecare calculator are capacitatea de a conversa cu celelalte calculatoare ale altor filiale și cu calculatorul central de la filiala centrală. Tranzacțiile trebuie să fie realizate indiferent de locul în care a fost deschis contul clientului, iar clienții vor nu sesiza nici o diferența între acest sistem și un sistem centralizat (pe care acest îl înlocuiește în vremurile curente).
2. PROIECTAREA SISTEMULUI
2.1 Cerințe
Se consideră un sistem format din servere (Service Provider/SP) care găzduiesc diferite servicii în mod request-response (cerere-răspuns). Pentru a avea acces la resursele disponibile pe aceste servere, clienții trebuie să se autentifice. În Fig. 4 este prezentată arhitectura unui astfel de sistem. Fiecare dintre servere găzduiește un serviciu de autentificare, nu se bazează pe un punct central fix de autentificare.
Autentificarea clienților va fi asigurată de un mecanism Single Sign-On, care se va ocupa de identificarea clienților fără a-i interoga la fiecare conectare pentru informațiile personale. Pentru acesta se va folosi de certificatele generate la comandă de oricare dintre serverele din rețea. Rețeaua poate fi publică, deci informațiile trebuie protejate. Pentru acesta toate comunicațiile și datele vor fi criptate, și coordonate de protocoale de securitate sigure [28].
Componentele trebuie să fie compatibile cu mai multe platforme, și aceste componente vor fi distribuite intr-un API. Acesta pune la dispoziție o interfață simplă care permite crearea unui astfel de sistem propus cu ușurință, permițând dezvoltatorului să se concentreze pe celelalte aspecte ale proiectului.
2.2 Arhitectura sistemului
2.2.1 Proiectarea mecanismului Single Sign-on
Single Sign-on este o proprietate de control de acces a sistemelor software multiple, legate, dar independente [6, 21]. Cu această proprietate, utilizatorul se autentifică doar o singură dată, iar identificarea se face de către sistem, de câte ori va fi nevoie, la fiecare furnizor din rețea. Așa cum s-a mai menționat, sistemul propus va fi alcătuit din „noduri”, independente unul de altul, dar fiecare știe de celălalt. Aceste „noduri” care în cazul nostru vor fi servere, și mai concret modulul XServer, vor găzdui două tipuri de servicii: unul pentru autentificarea, controlul accesului și autorizarea clienților, și unul pentru distribuirea resurselor. Fiecare server are capabilitatea de a efectua aceste procese, nu depind de un alt nod central, astfel adăugarea nodurilor noi se face fără probleme.
Clienții sunt înregistrați la unul dintre aceste servere, fiecare client are un home server. Acest home server se diferențiază de celelalte, doar din punctul de vedere al acelui client, care este înregistrat la el, și doar din punctul de vedere al autentificării, restul facilităților sunt disponibile în aceeași măsură. Altfel spus, fiecare server este un home server pentru toți clienții înregistrați la el. Înregistrarea se poate face în orice mod, fie prin e-mail, o pagină web, manual de către administratorul serverului, important e ca după înregistrare clientul să aibă acreditări, de orice tip (de obicei numele de utilizator și parola) stocate și protejate de server. Aceste informații personale vor fi păstrate secrete, oricine poate lua rolul unui client dacă are în posesie aceste date.
Un server poate să furnizeze resurse clienților, fie acestea fișiere locale, de orice tip, fie date de flux. În cadrul lucrării o să numim aceste servere, servere de resurse, resource server, sau service provider(SP). Toate datele trimise către și de serviciul de resurse vor fi criptate, cu chei generate la autentificare, explicat în următoarele paragrafe. Dacă un server nu rulează serviciul de resurse, atunci va avea rolul doar dea autentifica utilizatori, și de a trimite lista cu celelalte servere la cererea acestora. Serverele nu sunt limitate doar la aceste două servicii, ci se pot implementa numeroase și diferite tipuri de servicii, de exemplu serviciu de nume, webmail, FTP, etc. Un model al unui sistem descris se poate vedea în Fig. 4, unde trei clienți sunt conectați la mai multe servere de resurse ale rețelei.
Pentru a se folosi de serviciile serverelor de resurse, un utilizator trebuie să fie autentificat și să aibă drepturi de acces suficiente pentru această acțiune. Autentificarea este un proces prin care o entitate verifică dacă o altă entitate este cine sau ce pretinde a fi. Această entitate poate fi un utilizator, un cod executabil sau un calculator. Verificarea identității unui proces de la distanță este dificilă și necesită protocoale complexe de securitate bazate pe criptografie. Autentificarea în modelul meu se face pe baza numelui de utilizator și parolă. Clientul se va conecta la home serverul lui, adică unde a fost înregistrat, iar serverul verifică dacă este salvat vreun utilizator cu acel nume la el. Dacă numele clientului se regăsește în baza de date la server, se începe protocolul de autentificare care va asigura transmiterea datelor clientului în siguranță. (pasul 1 din Fig. 5) Protocolul se folosește de infrastructura cheilor publice, și va cripta mesajul clientului cu cheia publică a serverului. Dacă vreun client nu are cheia publică a unui server la care vrea să se conecteze, sau certificatul nu este valid, înainte de conectare va cere certificatul clientului de la serverul respectiv, care conține cheia publică.
După recepționarea datelor personale de la client, home serverul va verifica dacă numele de utilizator și parola furnizată se potrivesc cu cele din baza de date, ceea ce se poate vedea în Fig. 5, pasul 2. Aceste informații secrete a clientului vor fi trimise doar o singură dată, asta fiind important nu numai din punctul de vedere al confortului, ci și al securității. După autentificare, serverul va genera perechea de chei RSA și certificatul clientului. Aceste certificate vor fi folosite de acum încolo pentru autorizare în sistem, deci trebuie să fie create și folosite în așa fel încât să asigure un nivel securitate ridicat. Acest certificat va conține câteva informații despre utilizator (numele, locația, organizația, adresa e-mail, etc), despre certificat (algoritmul de criptare, rezultate hash, data expirării), dar și date despre emitent, pentru verificarea autenticității. Certificatul este semnat digital cu cheia secretă a serverului, protejând-ul astfel de orice modificare a conținutului acestuia. Certificatele folosite de mine, X.509v3, permit adăugarea unor extensii la setul de câmpuri predefinite, unde se pot înscrie comentarii sau date alese de utilizator. Aceste câmpuri vor conține permisiunile clienților care vor servi la controlul accesului în rețea, după un model bazat pe roluri (role-based access control / RBAC) [8]. Controlul accesului se referă la acordarea sau refuzul de privilegii la o entitate după autentificare. Un privilegiu este un drept pe care îl are un utilizator. Unele operații sunt considerate privilegiate și trebuie atribuite doar persoanelor de încredere.
Utilizatorilor nu se vor atribui direct permisiunile, ci aceștia le vor dobândi prin rolurile pe care le iau în cadrul rețelei. Astfel gestionarea permisiunilor utilizatorilor, sau adăugarea permisiunilor utilizatorilor noi se face ușor. Rolurile sunt salvate în aceeași bază de date ca și numele de utilizator și parola. În pasul 3, Certificatul și cheia secretă vor fi trimise clientului via canale securizate. Clientul are în posesie un certificat valid, care poate fi folosit ca un „pașaport” pentru a se mișca liber și a primi acces la oricare dintre servere din rețea unde are permisiune. Certificatul și cheia secretă vor fi salvate pentru alte dăți, având o valabilitate îndelungată, atâta timp cât acesta nu a expirat, poate fi folosit pentru a se conecta la alte servere. Dacă a expirat, se contactează home serverul, și se repetă pașii 1-3.
Pasul 4 din Fig. 5 reprezintă conectarea la unul dintre serverele de resurse, folosind certificatul generat anterior. Serverul verifică certificatul, adică numele să fie identic cu cel al clientului, să nu fie expirat, să fie emis de un server cunoscut din rețea și semnătura digitală a emitentului. Pentru verificarea semnăturii se folosește cheia publică a serverului care a generat certificatul. De regulă fiecare server are o copie după certificatele ale celorlalte servere din rețea, dar în caz contrar se poate face rost de el cu ușurință, cunoscând adresa serverului (pasul 5). Dacă verificarea a fost efectuată cu succes, și clientul are drepturi de acces la acel server, se va genera o cheie secretă. Această cheie se va folosi pentru criptarea datelor atât de la client la server cât și vice-versa. Cheia va fi folosită de algoritmul de criptare simetric, AES, și este validă doar pentru sesiunea curentă. Dacă cheia a expirat, clientul va trimite încă o dată certificatul pentru a solicita o altă cheie. Durata de viață scurtă a cheilor asigură o protecție ridicată împotriva atentatelor asupra rețelei. Cererile către serviciul de resurse și datele trimise ca răspuns de către server vor fi criptate cu această cheie.
2.2.2 Componentele sistemului
În Fig. 6 este prezentată arhitectura propusa a sistemului pentru care s-au formulat cerințele. Sunt prezentate componentele din care este format și legăturile dintre acestea.
Sistemul este format din următoarele componente:
XServer: găzduiește diferite servicii, cu diverse funcționalități. Numărul acestor servicii nu este limitat, dar în modelul meu folosesc doar un serviciu de autentificare și unul de resurse. Serviciul de autentificare este responsabil de identificarea clienților, prin conectarea la baza de date, generarea certificatelor și a cheilor pentru aceștia, și trimiterea listei cu serveri. Serviciul de resurse încarcă fișierele cerute, îi criptează și transmite datele înapoi la client, bineînțeles doar după autentificare.
XClient: componenta oferă o interfață pentru conectare la servere, autentificare, cerere lista de serveri, lista de fișiere, cerere de fișiere și scrierea acestora pe o unitate fizică. Conectarea se face automat, fără intervenția utilizatorului, așa cum și decriptarea fișierelor primite.
Baza de date: fiecare server se poate conecta la o bază de date pentru a stoca utilizatorii înregistrați. Aceste date se accesează de către serviciul de autentificare doar o singură dată pentru fiecare client. Baza de date mai conține o listă cu fiecare server disponibil din rețea.
2.2.3 Proiectarea componentei XServer
Componenta este responsabilă de rularea serviciilor, care la rândul lor sunt și ei componente, permițând crearea, înlocuirea sau adăugarea acestora la fiecare server. După cum s-a menționat anterior, în modelul meu voi folosi două servicii: unul pentru autentificare și unul pentru gestionarea resurselor.
Serviciul de autentificare este cea mai complexă componentă din model. Ea se ocupă în primul rând de actualizarea listei cu serveri, și informarea clienților de această listă, la comandă. Clienții înregistrați la un server sunt gestionate de acest serviciu, identificarea lor se face pe baza numelui de utilizator și a parolei, și pe baza acestor informații serviciul generează certificatul și cheile RSA pentru fiecare client. Autentificarea cu certificat este procesat tot de această componentă, astfel toate protocoalele de securitate sunt rulate de acest serviciu. La sfârșitul autentificării se generează o cheie secretă pentru sesiunea curentă, și se comunică această cheie cu serviciul de resurse. Componentele majore al serviciului de autentificare și a relațiile dintre ele se pot vedea în Fig. 7.
Principalele module interne ale componentei de autentificare sunt:
XAuthService: reprezintă modulul principal care se ocupă de acceptarea conexiunilor clienților [29, 31]. La conexiune acesta creează o instanță a modulului XAuthConnectionHandler. Totodată se ocupă de eliberarea memoriei, distrugerea modulelor inactive, notificarea serviciului de resurse de utilizatorilor noi și preluarea mesajelor de la alți participanți.
Listen Thread: firul de execuție generează evenimente care vor rula anumite funcții ale modulului. Aici se creează canalele de comunicație, se verifică starea fiecărui modul activ și preluarea mesajelor.
TCP Server Channel: implementează soclurile (socket) care acceptă conexiuni și date. Se ocupă de distribuirea mesajelor între componente.
Service Handler: gestionează serviciile create pentru fiecare conexiune. Creează și distruge canalele de comunicație folosite pentru toate transmisiunile de date.
XAuthConnectionHandler: modulul este creat de către XAuthService la fiecare conexiune nouă. Această componentă se ocupă de tot procesul de autentificare și generare de certificate și chei [31].
Service Controller: inițializează și controlează unele funcționalități al modulului, comunică cu XAuthService.
Final State Machine: automatul finit controlează cursul protocoalelor de securitate, setând stările potrivite pentru o bună funcționare a acestora.
Security Protocol Runner: aici sunt implementate majoritatea protocoalele de securitate. Accesează baza de date, controlează componenta OpenSSLWrapper, generează răspunsurile pentru clienți și verifică datele din mesaje la fiecare pas.
OpenSSLWrapper: încapsulează toate funcțiile OpenSSL folosite în proiect și inițializează librăriile OpenSSL. Conține mai multe clase care pot fi folosite separat pentru diferite procese. Modulul XAuthConnectionHandler folosește majoritatea acestor clase: wrapperul pentru criptare simetrică și asimetrică, diferite funcții legate de crearea, folosirea, încărcarea, scrierea și verificarea certificatelor; clase pentru crearea și verificarea semnăturilor digitale, generatoare de randomuri.
Performance Counter: măsoară timpul de execuție a anumitelor procese în timpul rulării. Unele informații sunt salvate într-un fișier jurnal.
Componenta XServer este pornită automat cu apelarea funcției StartServices() la nivelul cel mai de sus, din API-ul public. Înainte de pornire se pot seta anumite proprietăți al serverului, de exemplu directorul care conține resursele. În Fig. 8 se poate vedea secvența de inițializare mult simplificată a modulului XServer.
După pornirea serviciilor, modulul XServer creează cele două servicii, care la rândul lor sunt inițiate, și se trec în stare de așteptare de conexiuni noi de la clienți.
Autentificarea unui client. În Fig. 9 este prezentată diagrama de secvență a autentificării unui client nou la componenta de autentificare. Pentru a porni procesul de autentificare, clientul emite o cerere de conectare. Dacă clientul nu are încă un certificat valid, atunci se va conecta prima dată la serverul gazdă(home server), unde va fi verificat în baza de date dacă este înregistrat sau nu. Dacă informațiile de identificare au fost corecte, home serverul va genera un certificat cu datele personale și permisiunile clientului, cât și perechea de chei RSA și va transmite aceste date clientului. Dacă clientul are deja în posesie un certificat valid, poate să sară peste pașii de la serverul gazdă, și va iniția o conexiune la serverul de resurse. Acest server poate să fie chiar și home serverul. La conectare la serverul de resurse, clientul va trimite certificatul, iar serverul va verifica validitatea acestui folosind cheia publică a serverului care a emis acest certificat. Dacă nu are în posesie această cheie, va emite o cerere către acest server, și va solicita certificatul acestuia. Se verifică mai multe informații din certificat: validitatea semnăturii, data expirării, numele înscris în certificat trebuie să coincidă cu numele clientului, emitentul certificatului trebuie să aibă proprietatea de Certificate Authority (CA), etc. Dacă toate testele sunt trecute cu succes, serverul generează o cheie privată, valabilă doar pentru sesiunea curentă, și o va comunica clientului.
Serviciul de resurse pune la dispoziția utilizatorului fișiere găzduite pe serverul respectiv. La fiecare conectare cu succes la modulul de autentificare, numele utilizatorului și cheia acestuia vor fi înscrie într-o listă, care poate fi accesată de serviciul de resurse. La conectarea clienților la acest serviciu, se va căuta numele în acea listă. Dacă numele nu a fost găsit, fie încă nu s-a autentificat, fie a expirat cheia. Dacă numele a fost găsit în listă, se decodează cheia, și se folosește pentru decriptarea cererii clientului. Dacă decriptarea eșuează, înseamnă că cheia nu a fost corectă. În acest caz, clientul este deconectat. În caz contrar, se procesează mesajul clientului, si în funcție de natura acestuia se va genera răspunsul.
Momentan acest serviciu poate procesa două tipuri de cereri: să trimită lista cu fișiere disponibile, și să trimită unul dintre aceste fișiere înapoi la client. În primul caz se parcurge recursiv lista directoarelor care au fost adăugate ca resurse, și se construiește o listă cu toate fișierele, calea acestora și mărimea fișierului. Serviciul, și API-ul suportă filtrarea tipurilor de fișiere, pentru rezultate mai precise. Această listă cu fișiere va fi criptată cu cheia secretă, folosind algoritmul de criptare simetric AES, și trimis clientului. La recepționare se decriptează mesajul, se verifică integritatea listei, și se copiază in locație de memorie specificată de utilizator. În cazul celuilalt tip de mesaj, clientul solicită un fișier de la serviciu. Se decriptează cererea, se verifică dacă fișierul există și dacă se află în directorul de resurse. În caz afirmativ, se încarcă fișierul într-un buffer, și se criptează cu aceeași algoritm. La recepționarea fișierului de către client, ca și în cazul anterior, se decriptează și se copiază într-un buffer specificat de utilizator.
2.2.4 Proiectarea componentei XClient
Modulul XClient încapsulează toate procedurile pe partea de client necesare pentru a implementa mecanismul SSO descris în secțiunea 2.2.1. Interfața componentei ascunde marea parte a autentificării, totul se face automat, ușurând munca utilizatorului. Pentru a se conecta la orice server, se creează o instanță a componentei, și se apelează funcția pentru conectare. Se verifică dacă clientul posedă un certificat valid pentru a primi acces în sistem. Dacă acesta nu există, se inițiază primul protocol pentru a solicita și primi un certificat și cheile respective. Aceste protocoale includ câteva subprotocoale care vor fi descrise în secțiunea următoare.
Clientul se ocupă de salvarea și încărcarea acestor certificate și chei pentru fiecare utilizator în parte. După ce certificatul a fost verificat pentru autenticitate, se va trimite serverului care a fost selectat de utilizator inițial. Acest server va verifica certificatul încă o dată, de data asta va fi verificat și semnătura digitală cu cheia publică a emitentului. De obicei aceste certificate care conțin cheile publice a serverilor sunt salvate la fiecare participant, fiindcă se schimbă destul de rar, iar în caz contrar, fiecare server suportă un protocol simple pentru a trimite certificatul propriu solicitanților. Dacă certificatul clientului a fost găsit autentic, se trimite cheia de sesiune via al doilea protocol de securitate. Clientul va folosi această cheie până la deconectarea de la acest nod, sau până expiră pe partea serverului. Generarea unei chei noi și protocolul de transport se vor efectua la fiecare conectare, acesta având nevoie, în condiții optime, de 100 de milisecunde timp de rulare, ceea ce practic nu este detectabil de utilizator.
După conectare, sunt disponibile două funcții pentru a interacționa cu serverul: unul pentru a cere lista de fișiere găzduite aici, și altul pentru a solicita un fișier din această listă. Filtrarea listei în funcție de extensia fișierelor se poate face pe partea de client, pentru a găsi obiectul căutat mai ușor. Momentan nu există un indicator de progres pentru transferul fișierului, dar se poate adăuga mai târziu. Interfața mai oferă câteva funcții, ca de exemplu: interogarea componentei despre erori, solicitarea listei cu serveri din rețea, simularea unui pachet ping, pentru a măsura timpul de răspuns al unui server, scrierea fișierelor pe un dispozitiv de stocare fizic, schimbarea utilizatorului, etc. Toate aceste procese se fac automat și ascuns, dar totuși tot traficul între participanți este confidențial, datorită protocoalelor de securitate și criptografiei performante. Componentele majore și relațiile între ele sunt prezentate în Fig. 10.
Principalele module interne ale componentei XClientsunt:
XClient: reprezintă modulul principal care leagă componentele interioare între ele, și face legătura cu API-ul [22].
TCP Client Channel: implementează soclurile (socket) care comunică cu servere, prin protocoale TCP/IP. Se ocupă de distribuirea mesajelor între componente.
Service Handler: gestionează serviciile create pentru fiecare conexiune. Creează și distruge canalele de comunicație folosite pentru toate transmisiunile de date.
Component Wrapper: Reprezintă interfața dintre utilizator și componentele interne.
Final State Machine: automatul finit controlează cursul protocoalelor de securitate, setând stările potrivite pentru o bună funcționare a acestora.
Security Protocol Runner: aici sunt implementate majoritatea protocoalele de securitate. Accesează baza de date, controlează componenta OpenSSLWrapper, generează răspunsurile pentru clienți și verifică datele din mesaje la fiecare pas.
OpenSSLWrapper: încapsulează toate funcțiile OpenSSL folosite în proiect și inițializează librăriile OpenSSL. Conține mai multe clase care pot fi folosite separat pentru diferite procese. Modulul XAuthConnectionHandler folosește majoritatea acestor clase: wrapperul pentru criptare simetrică și asimetrică, diferite funcții legate de crearea, folosirea, încărcarea, scrierea și verificarea certificatelor; clase pentru crearea și verificarea semnăturilor digitale, generatoare de randomuri.
FileSystem IO: reprezintă setul de funcții care accesează fișierele necesare pentru funcționare.
2.2.5 Proiectarea bazei de date
Baza de date conține date legate de localizarea serviciilor în cadrul rețelei, cât și informații despre utilizatorii înregistrați la un server. În mod normal, fiecare server are o bază de date cu aceeași structură. În Fig. 11 este prezentată structura bazei de date.
Tabelul servers conține informații despre fiecare server în rețea. Aceste date sunt folosite pentru a forma lista serverilor la solicitarea clienților. Datele se citesc de fiecare cerere. Fiecare server are asociat un nume, o adresă și o opțional o descriere a serverului sau a resurselor găzduite. Tabelul users stochează datele despre utilizatorii înregistrați la serverul respectiv. Fiecare utilizator înregistrat are asociat un nume de utilizator, o parolă și un rol în cadrul rețelei. Aceste date se verifică la autentificare, și se generează certificatul pe baza lor.
2.3 Proiectarea interfeței de programare (API)
Componenta XClient asigură o interfață minimală, dar suficientă pentru implementare. Majoritatea funcțiilor sunt cu blocare, și au nume sugestive. Componenta oferă rapoarte detaliate în caz de eroare [25].
Constructorul: ia ca parametru numele de utilizator și parola, care vor fi folosite pe toată durata instanței. Aceste date se pot schimba mai târziu.
XClient( const std::string UserName, const std::string Password );
Connect: conectare la un server din rețea, adresa acestui server fiind precizat prin parametru. Clientul se conectează la home server și va solicita un certificat, în cazul în care nu are deja unul valid, iar după aceea la serverul precizat. Conectarea la cele două servere se face automat și cu blocare până terminare. Un al doilea parametru va returna numărul de milisecunde scurse până la obținerea certificatului respectiv a cheii pentru această sesiune. Funcția returnează o expresie booleană, semnificând reușita operației.
bool Connect( std::string ResourceServerAddress, double &TimeElapsed );
getLastErrorMessage: în caz de eroare, se apelează această funcție pentru a afla mai multe detalii legate de problemă, în formă de text.
std::string getLastErrorMessage();
getServerList: cere lista de serveri disponibili în rețea de la home server. Lista include adresa fiecărui server, cât și descrierea acestora. Funcția se poate apela oricând, nu necesită autentificare. Lista va fi stocată intr-un vector dat ca parametru. Funcția blochează firul de execuție în care se rulează până primește un răspuns de la server, sau expiră time-out-ul. Funcția returnează o expresie booleană, semnificând reușita operației.
bool getServerList( std::vector< ServerInfo* > &SList );
getFileList: se solicită lista de fișiere disponibile pe serverul curent. Funcția se apelează doar după o conectare cu succes la unul dintre serverele din rețea. Datele trimise și recepționate vor fi criptate cu o cheie secretă prestabilităla conectare. Lista va fi stocată într-un vector dat ca parametru. Lista va include numele, calea și mărimea în octeți pentru fiecare fișier. Funcția blochează firul de execuție în care se rulează până primește un răspuns de la server, sau expiră time-out-ul. Funcția returnează o expresie booleană, semnificând reușita operației.
bool getFileList( std::vector< FileInfo* > &FList, std::string Mask );
RequestFile: se solicită un fișier de la serverul curent. Funcția se apelează doar după conectare cu succes la unul dintre serverele din rețea. Datele trimise și recepționate vor fi criptate cu o cheie secretă prestabilită la conectare. Calea către fișierul dorit, cât și un buffer pentru stocarea acestuia vor fi date ca parametru. Funcția blochează firul de execuție în care se rulează până primește un răspuns de la server, sau expiră time-out-ul. Funcția returnează o expresie booleană, semnificând reușita operației.
bool RequestFile( std::string FileName, std::vector< char >&FileBuffer );
PingServer: simulează un ping către un server din rețea. Singurul parametru este adresa serverului ales. Funcția este cu blocare și returnează timpul trecut în milisecunde până la recepționarea răspunsului de la server.
int PingServer( std::string HostName );
WriteFile: scrie un fișier pe o unitate fizică pentru stocare. Primul parametru specifică calea către noul fișier, iar al doilea va fi bufferul care conține fișierul primit de la server. Funcția returnează o expresie booleană, semnificând reușita operației.
bool WriteFile( std::string FileName, std::vector< char >FileBuffer );
getCertificate: funcția returnează un certificat într-un format decriptat, doar pentru afișare. Singurul parametru precizează certificatul ales, 1 pentru a returna certificatul clientului, 2 al home serverului și 3 al serverului de resurse.
std::string getCertificate(int Select);
SwitchUser: permite schimbarea utilizatorului, fără a crea o instanță nouă XClient. Noul utilizator va trebui să se reconecteze la unul dintre serverele disponibile. Parametrii vor conține numele de utilizator, adresa home serverului, și parola utilizatorului. Funcția nu returnează o valoare.
void SwitchUser( std::string UserName, std::string Password );
Componenta XServer pune la dispoziție câteva funcții care permit crearea unui server de autentificare și de resurse funcțional.
Constructorul: are ca parametru numele serverului
XAuthServer( const tstring ServerName );
setResourceDir: permite selectarea dosarelor care vor conține fișiere resurse. Se pot preciza mai multe surse, separându-le cu virgulă. Aceste dosare vor fi parcurse recursiv de la fiecare cerere de listă de fișiere. Dacă serverul nu va găzdui resurse, se poate ignora această funcție. Funcția se apelează doar înainte de pornirea serverului.
void setResourceDir( tstring Directories );
startServices: pornește serverele de autentificare și de resurse în mod de ascultare. Conexiunile vor fi procesate automat. Ca parametru se pot specifica porturile de ascultare pentru cele două servere, sau 0 pentru a folosi porturile predefinite. Funcția blochează curentul fir de execuție până la oprirea serverului.
void startServices ( const int AuthServicePort, const int ResourceServicePort );
stopServices: oprește cele două servicii, clienții vor fi deconectați.
void stopServices();
2.4 Proiectarea protocoalelor de securitate
Comunicarea între componentele sistemului de autentificare se realizează prin schimb de mesaje pe soclu. Mesajele sunt parte a unor protocoale de securitate care au rolul de a păstra confidențialitatea datelor, identificarea și autentificarea participanților. Protocoalele diferă în funcție de componentele între care se desfășoară, dar și în funcție de scopul fiecărui protocol. Proiectarea protocoalelor s-a realizat pe baza principiilor prezentate în compartimentul 2.2.1. Protocoalele de securitate existente ca SSL(Secure Socket Layers) sau TLS (Transport Layer Security) sunt complexe, și conțin multe informații care nu ne folosesc în modelul meu. Fiindcă noi vrem să navigăm cu ușurință și rapiditate între serverele din rețea nu ne putem permite să avem date inutile în mesaje, de aceea am proiectat un set nou de protocoale, care conțin datele strict necesare pentru a atinge scopurile propuse. Protocolul complet este descris în Fig. 12, descrierea lui în secțiunea următoare.
Componentele mesajelor și ce anume semnifică acestea:
A – Home server (serverul unde este înregistrat clientul B), respectiv în mesaj nume server
B – Client, respectiv în mesaj nume client
C – Serverul de resurse ales pentru conectare, respectiv în mesaj nume server
N – Nonce, un număr aleator
(X)h – O funcție hash aplicată pe X
M – Cuvinte cheie folosite pentru identificarea tipul mesajului
KXY – Cheie simetrică cunoscută doar de X și Y
skX – Cheie secretă asimetrică a lui X, se decriptează cu pkX, folosit pentru semnături digitale
pkX – Cheie publică asimetrică a lui X, se decriptează cu skX
{|X|}Y – X criptat cu cheia Y
CertX – Certificatul lui X, care conține și cheia publică
Sig – Semnătură digitală
2.4.1 Protocolul de autentificare la home server
Pentru a primi acces la serviciul de resurse, un utilizator trebuie să aibă un certificat valid. Serverul generează aceste certificate la cerere, pe baza numelui de utilizator si a parolei. Aceste informații sunt stocate într-o bază de date sigură, pe partea serverului, dar transmiterea lor nu se poate face direct, pentru că oricine poate asculta comunicația în rețea. Acest protocol de securitate va garanta transmisia lor în secret. Protocolul se efectuează ori de câte ori este nevoie de un nou certificat, dar pentru că certificatul este salvat, asta se întâmplă în mod normal doar după expirarea certificatului. Pașii protocolului de autentificare [1, 17]:
1. B → A: M, B
2. A → B: M, N(h)
3. B → A: {|(N)h, B, M, KAB|}pk(A)
4. A → B: {|(N)h, CertB, {|skB|}K(AB) |}sk(A)
Primul pas reprezintă inițierea conexiunii de către client (B). Mesajul conține tipul mesajului, acesta fiind solicitare de autentificare pe baza parolei, și numele clientului. Serverul (B) decide dacă poate accepta o nouă conexiune, și verifică dacă numele clientului se găsește la el în baza de date. În caz afirmativ, se generează un nonce, se aplică funcția hash, și se trimite înapoi clientului. Mesajul serverului va conține fie acceptarea conexiunii, fie un mesaj de eroare cu motivul eșuării. Dacă conexiunea este acceptată, clientul va aplica aceeași funcție hash pe hashul primit de la server, și va genera o cheie simetrică care va fi folosită pentru criptarea cheii secrete din certificat. Clientul în acest moment are în posesie certificatul serverului, fie avându-l salvat, fie cerându-l înainte de inițierea conexiunii. Acest certificat conține cheia publică a serverului (pkA), și va fi folosit pentru criptarea părților secrete a mesajului, adică nonce-ul, numele de utilizator, parola și cheia generată. Datele binare sunt codate cu Base64 înainte de trimitere. Acest text cifra poate fi decriptat doar cu cheia secretă a serverului (skA), iar după decriptare, se verifică prima dată nonce-ul. Acesta se face prin aplicarea funcției hash pe hash-ul salvat în pasul anterior, și compararea rezultatului cu cel din mesajul trimis de client. Dacă cele două șiruri nu coincid, se trimite un mesaj de eroare, și se termină conexiunea. Acesta este un Dacă verificarea a fost efectuată cu succes, semnificând că mesajul este recent, se caută numele clientului în baza de date și se compară parola trimisă de client cu cea stocată în baza de date. După acesta se generează certificatul pentru client, care va conține numele și permisiunile solicitantului, numele emitentului, perioada de validitate, cheia publică generată și alte informații necesare pentru verificarea certificatului.
Certificatul este semnat digital cu cheia secretă a serverului. Perechea cheii din certificat este criptat cu cheia generată de client. Hash-ul nonce-ului este procesat similar ca în pasul precedent, și împreună cu cheia criptată și certificatul generat vor fi criptate cu cheia secretă a serverului, adică semnat digital. Acesta este un test de autentificare de intrare, pentru că nonce-ul trimis va fi reprimit de către client într-o formă criptată cu o cheie care este cunoscută numai de către server. Mesajul este autentic, dar pentru a se asigura că este și recent, se verifică nonce-ul. Cheia secretă este decriptată cu cheia generată anterior, și va fi salvat împreună cu certificatul generat.
2.4.2 Protocolul de autentificare la serverul de resurse
După ce clientul are un certificat valid, se poate folosi de el pentru a primi acces la anumite servere din rețea, în funcție de permisiunile fiecăruia. Acest certificat ar fi de ajuns pentru a se autentifica și pentru a transmite date criptate, dar algoritmul de criptare RSA este mai încet decât algoritmii de criptare cu chei simetrice. De aceea, cu ajutorul cheilor din certificat se negociază o cheie secretă simetrică, care va fi folosit pentru criptarea datelor între client și serverul de resurse ales. Pentru că cheile simetrice pot fi descoperite mai ușor decât cele asimetrice, o cheie nouă se va genera la fiecare conectare, și va fi valabilă doar pe durata sesiunii curente. Această cheie trebuie să rămână secretă, dar fiindcă este generat de către server, transmisia ei necesită „protecție”, oferită de acest protocol de securitate. Protocolul este inițiat de client la fiecare conectare la orice server de resurse, și are următorii pași [17]:
1. B → C: M, B
2. C → B: M, N(h)
3. B → C: CertB,{|(N)h |}sk(B),Sig
4. C → B: {|{|(N)h, KBC|}pk(B) |}sk(C)
În primul pas clientul (B) inițiază conexiunea, trimițând numele și tipul mesajului: autentificare cu certificat. Serverul răspunde fie cu acceptare, fie cu un mesaj de eroare și motivul acestuia. Mesajul va conține și un nonce generat de acest server. Clientul aplică funcția hash asupra nonce-ului, și îl semnează cu cheia lui secretă. Această semnătură și certificatul va fi trimis înapoi serverului. Nonce-ul semnat poate fi verificat cu cheia publică din certificat, dar înainte de acesta, trebuie verificat și autenticitatea certificatului. Se verifică hash-urile din certificat, perioada de valabilitate, anumite flaguri care specifică dacă emitentul este sau nu un Certificate Authority (CA), și bineînțeles semnătura din certificat. Această semnătură a fost făcută cu cheia secretă a emitentului, deci se verifică cu cheia publică pereche. Dacă acest server nu are certificatul serverului emitent, îl solicită și extrage cheia publică pentru a verifica semnătura din certificat. Dacă certificatul nu poate fi validat, autentificarea va eșua. În caz contrar, se extrage cheia publică din certificat și se verifică semnătura clientului. Și aici întâlnim un test de autentificare de intrare, pentru că elementul criptat intră: …N… →{|…N…|}. Acest test asigură că mesajul este recent și că este trimis de posesorul certificatului. Opțional, se verifică permisiunile înscrise în certificat, și în funcție de regulile serverului anumite clase de utilizatori sunt filtrate. Se generează o cheie privată, și împreună cu nonce-ul hash-uit, este criptat cu cheia publică a clientului, extras din certificat.
Tot mesajul este semnat digital de către server și transmis clientului. La recepționare se decriptează mesajul, și se verifică nonce-ul, comparându-l cu cel salvat anterior. Se verifică și semnătura digitală a serverului, și se salvează cheia de sesiune. Această cheie va fi folosit doar o singură sesiune, și doar cu acest server. Toate cererile de resurse și răspunsurile sunt criptate cu această cheie. La reconectare se rulează acest protocol încă o dată pentru a genera o cheie nouă.
2.4.3 Protocolul de solicitare certificat
Sistemul Single Sign-on este construit pe o infrastructură cu chei publice, unde certificatele sunt elementele de bază. De aceea fiecare protocol de autentificare are nevoie de certificatele serverelor participanți. Pentru asta am creat un alt protocol simplu care solicită certificatul serverului precizat și îl salvează local. Pentru că în cazul meu cel mai important aspect după securitate este simplitatea, acest protocol conține doar doi pași [20, 30]:
1. X → Y: M, X
2. Y → X: M, CertY
Primul pas specifică tipul mesajului și numele solicitantului, iar al doilea pas conține rezultatul cererii, și certificatul solicitat. Fiindcă certificatul conține toate elementele de securitate pentru a verifica autenticitatea lui, nu este nevoie de un protocol complex pentru a asigura transmisia acestuia.
2.5. Concluzii la compartimentul 2
În acest compartiment au fost stabilite cerințele pentru sistemul propus spre realizare. Este alcătuită arhitectura sistemului cu cu proiectarea mecanismului Single Sign-on, a componentelor Xserver Xclient și a bazei de date respective. S-a proiectat interfața de programare (API). De asemenea au fost proiectate protocoalele de securitate: protocolul de autentificare la home server, protocolul de autentificare la serverul de resurse și protocolul de solicitare certificat.
În continuare se va trece la implementarea și testarea sistemului propus de autentificare, autorizare șu control al accesului.
3. IMPLEMENTAREA SISTEMULUI
3.1. Arhitectura internă a claselor
La baza sistemului stau clasele construite cu librăriile NSPR, și care ofer funcționalități simple, de exemplu: fire de execuție, socluri, parsere, containere și elemente de legătura cu clasele la nivele mai înalte.
O altă grupă de clase este cea de securitate, asta include clasele care se conțin funcționalități pentru crearea, încărcarea, verificarea certificatelor, criptografie, funcții hash, semnături digitale, generatoare de nonce-uri, etc. Aceste clase au fost construite folosind librăriile OpenSSL.
Canalele de comunicație sunt moștenesc soclurile și firele de execuție, pentru a oferi un control mai avansat al fluxului de mesaje. Acesta se realizează apelând funcții callback. Gestionarea canalelor se face cu ajutorul clasei XChannelHandler, care creează și șterge canalele.
Peste aceste canale sunt construite serviciile, care deja au funcționalități complexe. Sunt două tipuri de servicii, client și server, fiecare are canale de comunicație, care vor transmite mesajele. Gestionarea serviciilor se face de clasa XServiceHandler, cu ajutorul căreia se pot crea și șterge serviciile.
3.1.1 Clasele de bază
În această secțiune sunt prezentate clasele mai importante care sunt folosite pentru a construi componentele principale, amintite anterior.
Clasa XThread (Fig. 13) implementează datele necesare și funcționalitatea unui fir de execuție așa cum este el definit de NSPR. Printre datele membru se regăsește m_Thread, descriptorul firului de execuție și două variabile de tip boolean m_bRunning și m_bExited utilizate pentru a semnala starea firului. Funcțiile membru start(), stop() sunt folosite pentru a porni, respectiv a opri firul de execuție. Pentru a lansa un fir de execuție trebuie derivată o clasă din XThread și suprascrisă metoda Run(), instanțiată clasa, apoi se va apela metoda start(). Firul de execuție va rula până când metoda Run() își va încheia execuția sau este apelată metoda stop(). Metodele isRunning() și isExited() returnează starea firului de execuție.
Clasa XTwinThread încapsulează două fire de execuție, unul prin moștenirea clasei XThread, iar al doilea printr-un membru de tipul clasei XThreadRunner care moștenește la rândul ei clasa XThread. Membrul mthread este un pointer către instanța clasei XThreadRunner iar metodele tstart(), tstop(), tisRunning() și tisExited() se folosesc pentru a porni, opri, respectiv interoga starea celui de-al doilea fir de execuție.
Clasa XTCPSocket (Fig. 14) încapsulează funcționalitatea unui soclu utilizat pentru a stabili conexiuni TCP/IP. Printre datele membru este mSocket, descriptorul obiectului soclu. Funcțiile getData(char* buffer,int bufSize) și sendData(char* buffer,int bufSize) sunt folosite pentru a recepționa date pe soclu, respectiv pentru a trimite date.
Clasa XTCPServerSocket moștenește în mod direct clasa XSocket și implementează metode pentru a pune un soclu în starea de “ascultare” și pentru a accepta cereri de conexiune. Aceasta oferă în plus fața de clasa XSocket două metode: Listen() și Accept() folosite pentru a pune soclul în starea de ascultare, respectiv pentru a accepta o conexiune.
Mai conține și un membru m_port folosit pentru a specifica pe ce port să se pornească ascultarea. Fig. 14 – Cltjstj XTCPSocket
Clasa XTCPClientSocket moștenește în mod direct clasa XSocket și implementează metode pentru a realiza o conexiune cu un server. Aceasta oferă în plus față de clasa XSocket câteva metode: Connect() pentru a iniția o cerere de conexiune și isConnected() prin care se poate interoga starea soclului (dacă este sau nu conectat). Printre membri acestei clase se pot aminti următorii: pAddr și m iPort prin care se specifică adresa și portul pe care să se facă conectarea și m bConnected utilizat pentru stabilirea stării soclului, valoarea sa putând fi setată prin intermediul metodei setConnectionStatus() și obținută prin intermediul metodei isConnected().
Clasa TCPServer încapsulează clasa XServerSocket, și XTwinThread, și oferă funcționalitatea unui server, adică ascultă pentru conexiuni noi, atât timp cât membrul privat mbShouldRun este true. Tot aici se vor apela funcțiile callback care vor fi suprascrise în clasele care vor moșteni clasa TCPServer. Oferă trei funcții pentru a interacționa cu serverul: createServer(), runServer() și stopServer(), rolul cărora sunt evidente.
Clasa TCPTransport încapsulează clasa XClientSocket, dar este folosit atât pe partea clientului cât și pe partea serverului, ocupându-se de transportul datelor. Apelează funcțiile callback, la orice eveniment de receive sau send, atât timp cât membrul privat mbShouldRun este true.
Un obiect care stă la baza transportului de date este clasa XMessage (Fig. 15), care conține toate setările necesare ca datele să ajungă la destinație, cât și datele în sine. Clasa oferă stocarea datelor atât în format raw, neformatat, cât și într-un format delimitat, având funcționalitatea unui parser.
Clasa XSimpleParser (Fig. 15) este folosit foarte des, deoarece se ocupă de prelucrarea mesajelor, și a datelor în general. Prelucrarea în cazul acestui parser înseamnă despărțirea întregului șir în mai multe părți (tokenuri), iar delimitatorul este specificat de utilizator la instanțierea obiectului. Metodele publice includ funcții pentru a returna numărul acestor tokenuri, verificarea dacă conține un anumit subșir, returnarea fiecărui token separat, etc.
Clasa XSimpleList (Fig. 15) încapsulează lista din librăriile standard [13], adăugând câteva funcții pentru compatibilitate cu celelalte clase din proiect.
Clasa XBase64Coder (Fig. 15) oferă codare și decodare în popularul format standardizat Base64 [16]. Acest format permite trimiterea datelor binare între participanți fără a pierde integritatea datelor. Clasa stochează rezultatul și mărimea acestuia în membrii privați m_pResult respectiv m nResultSz. Funcțiile publice encode() și decode() sunt folosite pentru codarea și decodarea datelor, iar rezultatul și mărimea rezultatului sunt returnate de funcțiile getResult() respectiv getResultSize().
3.1.2. Clasele de securitate
Clasele OpenSSL sunt construite pe librăriile OpenSSL, și se folosesc pentru a implementa facilitățile de securitate. Diagrama de clase este prezentată în Fig. 16.
Majoritatea claselor au un membru privat care conține datele procesate, și funcții de tip „getter / setter” pentru accesarea lor.
Clasa DigitalSignatureCreator creează semnături digitale pe baza datelor de intrare și a unei chei transmise ca parametrii în funcția signData(). Semnătura și hash-ul acesteia pot fi accesate prin funcțiile respective. Această clasă oferă si verificare prin funcția verifySignature(), care ia ca parametru datele semnate digital și o cheie.
Clasa HashCreator, cum spune și numele, aplică o funcție hash pe datele introduse. Clasele CertificateCreator, CertificateChecker și CertificateLoader conțin proceduri pentru gestionarea certificatelor. Cum spune și numele, CertificateCreator generează certificatele pe baza datelor trimise ca argumente funcției CreateCertificate(). Informațiile necesare pentru generarea certificatului sunt prezentate în secțiunea 2.4. Tot aici se generează și perechea de chei RSA.
Clasa CertificateChecker verifică certificatele, după anumite criterii specificate ca parametru pentru funcția VerifyCertificate(). Funcția getPermission() citește permisiunile clienților pentru controlul accesului în rețea. Clasa CertificateLoader are rolul de a încărca certificatele stocate pe un dispozitiv fizic. Funcțiile getPrivateKey() și getPublicKey() extrag cheile specificate din certificat, care a fost încărcat folosind funcția loadCertificate() respectiv din fișierul cu cheia privată, folosind funcția loadPrivateKey().
Funcția hashData() ia ca parametru datele de intrare și tipul algoritmului hash. Algoritmii suportați sunt MD5 și SHA1. Rezultatul se returnează cu funcțiile getHash() și getHashSize().
Clasa RandomCreator generează numere aleatorii, care sunt folosite în orice protocol de securitate. Un număr 100% aleatoriu este imposibil de generat folosind numai calculatorul, de aceea aceste numere sunt doar pseudorandom-uri. Totuși se încearcă să fie influențat de cât mai multe surse întâmplătoare posibil. Acesta folosește timpul calculatorului combinat cu valori din stivă. Funcția generateRandom() creează un număr de mărime specificată ca parametru. Rezultatul este returnat de funcția getRandData().
Clasa AszmmEncCreator încapsulează funcțiile de criptografie simetrică din librăriile OpenSSL. Suportă toate algoritmele disponibile în aceste librării. Pentru selectarea algoritmului și specificarea cheii folosite se apelează funcția initEncryptionCtx(). După inițializare se pot apela funcțiile encryptData() și decryptData() pentru criptarea respectiv decriptarea datelor. Rezultatul se obține apelând funcția getData() iar mărimea rezultatului prin funcția getDataSize().
3.1.3. Canalele de comunicație
Prin folosirea funcțiilor callback a claselor TCPServer și TCPTransport se creează o listă care va conține obiecte de tip XMessage, cu ajutorul cărora se va efectua transmisia datelor. Canalele sunt reprezentate de clasa XIChannel, care gestionează această listă cu mesaje, m msgList. Identificatorul canalului este stocat în membrul mnChannelID, iar de funcțiile callback se ocupă m_pchCallback. Aceste variabile sunt accesabile prin metodele „getter” și „setter”: getChannelIDQ, setChannelIDQ, addMessage(), getChMessage().
Clasa XHandlerImplementation moștenește clasele XlChannelCallback și XThread, și se ocupă de gestionarea canalelor și redirecționarea mesajelor la destinația potrivită. Firul de execuție, pornit cu run(), citește datele recepționate, și decide canalul pentru care este destinat acesta. Canalele sunt create și distruse de acest obiect, prin funcțiile createChannel() și destroyChannel(). Membrul m channelMap stochează toate canalele create. Mesajele sunt trimise canalelor prin funcțiile sendToChannel() și getMessage(), iar mesajele interne sunt trimise funcției handleInternalChMessage() pentru procesare locală. Clasa XChannelHandler este un wrapper pentru clasa XHandlerImplementation.
Clasele XTCPServerChannel și XTCPClientChannel moștenesc unele clase menționate anterior, și adaugă anumite funcționalități specifice canalelor server / client, și se ocupă de crearea și verificarea header-urilor mesajelor.
Diagrama de clase a canalelor de comunicație este prezentată în Fig. 17.
3.1.4. Servicii
Serviciile încapsulează canalele de comunicații și au o structură similară cu acestea: funcțiile callback generează evenimentele când se recepționează un mesaj. Aceste mesaje sunt trimise canalelor, iar de la canale la servicii. Gestionarea serviciilor se face de către un obiect global, ca și XChannelHandler-ul. La crearea serviciilor, se setează proprietățile fiecăruia în parte. Acest lucru se face cu ajutorul structurii servicejnfo, care conține tipul noului serviciu, portul de ascultare, și configurări opționale.
Elementul de bază este XlService care la rândul lui moștenește clasa XThread. Această clasă este abstractă, și definește structura clasei care o va încapsula. Acesta va fi XBaseService care are deja funcționalitățile unui serviciu. Membrii privați stochează ultimele mesaje (m lstMessages), o instanță a XChannelHandler-ului, prin care se va face transmisia datelor (m_pChannelHandlef), proprietățile serviciului (m svInfo), și identificatorului canalului principal (m nMainChannellD). Majoritatea funcțiilor membri a clasei sunt virtuale, și folosite ca funcții callback pentru clasa care va moșteni acest obiect. Aceste funcții sunt apelate la evenimentele generate de mesaje primite, care sunt verificate în funcția run a firului de execuție. Funcțiile includ notificări pentru crearea, distrugerea, configurarea canalelor, furnizează informații despre starea canalelor, și trimit notificări în cazul în care s-au recepționat mesaje pe canal.
Clasa XServiceDeployment gestionează serviciile, se ocupă de crearea acestora și expedierea mesajelor. Toate serviciile active sunt stocate în variabila m serviceMap. Distrugerea și configurarea serviciilor, cât și rutarea mesajelor se face la nivele mai joase. Clasa XServiceHandler este un „wrapper” pentru clasa XServiceDeployment. Diagrama acestor clase este prezentată în Fig. 18 iar Diagrama claselor de comunicație și relațiile între ele sunt prezentate în Fig. 19.
3.2. XServer
Funcționarea componentei este descrisă în secțiunea 3.2.3. Componenta este o încapsulare a clasei XServiceHandler, cu ajutorul căreia sunt create serviciile de autentificare și de resurse. După configurarea componentei, fluxul mesajelor și generarea notificărilor se face „automat” de către clasele de comunicație descrie mai sus.
Un serviciu se creează prin moștenirea clasei XBaseService. Această clasă conține în mare parte funcții virtuale, care trebuie suprascrie de către noul serviciu creat. Un fir de execuție se ocupă de citirea mesajelor și generarea notificărilor necesare. Funcțiile oferite de clasa XBaseService sunt vizibile în Fig. 18. Funcția onCreateChannel() este apelată de fiecare dată când o nouă conexiune este creată, și odată cu acesta un nou obiect XChannelHandler, pentru a gestiona fluxul mesajelor. La conectarea unui client se creează un obiect de tip XAuthSvConnHandler pentru serviciul de autentificare, respectiv XResSvConnHandler pentru serviciul de resurse. Aceste două clase moștenesc clasa abstractă XISvConnHandler, care recepționează mesajele pentru acest canal, și le procesează în funcție de tipul serviciului. Membrul privat m lstConnections este o listă care conține aceste obiecte de tip XISvConnHandler, și are rolul de a găsi destinatarii mesajelor la recepționare. De acesta se ocupă funcția onChannelDataMessage() care este apelată la fiecare mesaj recepționat. În acest moment lista cu conexiuni este parcursă și se caută canalul care are identificatorul la fel ca și mesajul primit. Dacă se găsește canalul, se apelează funcția processMessage(), în caz contrar se generează o eroare și se distruge canalul. Acest lucru declanșează o notificare care apelează funcția onDestroyChannel(). În această funcție se șterge obiectul care stoca conexiunea respectivă, și se eliberează memoria. O altă notificare se declanșează când un canal este inactiv pentru un timp mai lung. În funcție de implementarea serviciului, aici se pot lua unele măsuri în legătură cu acest canal. În sistemul meu, conexiunile sunt eliberate când sunt inactive. Diagrama de stare a clasei este prezentată în Fig. 20.
Clasele XISvConnHandler suprascriu funcția onMessage() care va fi apelată de fiecare dată când este recepționat un mesaj care are ca destinație acest canal. În această funcție se procesează mesajul, în cazul acesta se verifică header-ul mesajelor,se extrage informația utilă din acestea, și se trimite funcției processRequest(). Aici procesarea datelor este dependent de tipul serviciului. Diagrama de stare se poate vedea în Fig. 21.
3.2.1 Serviciul de autentificare
Serviciul de autentificare are următoarele roluri:
Autentifică utilizatorii pe baza numelui de utilizator și a parolei,
Autentifică utilizatorii pe baza certificatului,
Trimite certificatul propriu la cerere,
Trimite lista de serveri disponibili din rețea la cerere,
Măsurarea performanței de autentificare a clienților.
Fiecare server care rulează acest serviciu are aceste funcționalități, iar selectarea lor se face de către mașina de stare a sistemului. Stările sunt setate în funcție de conținutul mesajelor sau de pasul curent în procesul de autentificare. La acceptarea unei noi conexiuni în funcția onCreateChannel() se creează o nouă instanță a obiectului XAuthSvConnHandler, și se adaugă în lista m lstConnections. Periodic se verifică activitatea acestor conexiuni, și dacă sunt inactive, sau și-au terminat activitatea, sunt eliberate din memorie și șterse din listă. Mesajele sunt „recepționate” prin funcția onChannelDataMessage() și trimise ca parametru instanței XAuthSvConnHandler prin funcția processMessage(). În cazul în care nu este găsit proprietarul mesajului, se șterge canalul de comunicație. La distrugerea conexiunilor se citește membrul m_Time a instanței XAuthSvConnHandler, prin funcția getTime(), care conține timpul de rulare în cazul autentificării. Aceste informații sunt salvate într-un fișier local.
La crearea unui obiect XAuthSvConnHandler sistemul este inițiat și trece în stare de așteptare mesaje. La recepționarea unui mesaj se verifică integritatea acestuia, și se procesează. La procesare se setează starea sistemului în funcție de solicitarea clientului. Protocolul de autentificare are nevoie de mai mulți pași pentru terminare, așa că sistemul este configurat pentru a recepționa alte mesaje și ași continua autentificarea. Celelalte mesaje, și ultimul pas din fiecare protocol, după generarea și trimiterea datelor pun sistemul în starea finală, unde se eliberează memoria alocată în timpul rulării, și se setează variabila mbAllive, care indică starea conexiunii, false. Clasa XAuthService verifică această valoare periodic, și la terminare, dacă e cazul citește performanța autentificării, distruge și eliberează conexiunea. În Fig. 22 se vede diagrama de stare simplificată.
Funcționarea serviciului de autentificare mai detaliat, cu stările sistemului, sunt explicate în continuare. Sistemul inițial este în starea 0, unde se fac inițializările, și se trece în starea 1. Aici se așteaptă într-o buclă „infinită” până la recepționarea unui mesaj. Mesajul poate fi unul pentru configurarea sistemului, sau unul de la client, solicitând servicii.
La solicitarea listei cu serveri, se accesează baza de date pentru citirea datelor. Informațiile legate de server sunt formatate pentru trimitere, în formă de token-uri. Aceeași lucru se întâmplă și în cazul solicitării a certificatului. La cerere se încarcă certificatul în memorie, și se trimite clientului așa cum este, fiind deja codat cu Base64, permite transportul fără pierderea integrității. În acest timp, serverul este în starea 2. În ambele cazuri, după terminarea procesării, sistemul trece în starea finală unde conexiunea este terminată iar obiectul XAuthSvConnHandler este distrus și eliberat din memorie.
În cazul autentificării, clientul în primul pas trimite un mesaj exprimându-și intențiile de autentificare. Serviciul verifică numele clientului, și folosind RandomGenerator-ul, se generează un nonce. Acesta va fi salvat pentru pasul următor. Sistemul se trece iar în starea 1, așteptând mesaje, dar se salvează progresul autentificării. La recepționarea unui mesaj valid se trece în starea 4. Aici practic se desfășoară protocolul de autentificare, pașii detaliați includ: se decodează mesajul, folosind o clasă XBase64Coder, declarat global. Se decriptează mesajul cu cheia privată a serverului, și se verifică dacă sunt prezente toate token-urile necesare pentru acest pas. Se verifică nonce-ul trimis de client dacă coincide cu cel salvat în pasul anterior. Informațiile de identificare a clientului sunt verificate în baza de date, și se începe generarea certificatului. Funcția CertificateCreator::CreateCertificate() ia toate informațiile necesare pentru a completa câmpurile din certificat. Cheia publică se află în certificat, iar perechea este criptată cu cheia trimisă de client, tot în acest mesaj. La orice eșuare a verificării unui element se termină procesul, și se generează o eroare pentru client. Datele binare sunt codate cu Base64, și împreună cu alte informații și delimitatori, sunt stocate în variabile de tip std::string. Se adaugă o semnătură digitală, și se trimit datele. Sistemul trece în starea finală, eliberând memoria.
Dacă se solicită o autentificare cu certificat, sistemul trece din starea 1 în starea 5. Se generează un nonce, și se trimite clientului într-un mesaj de acceptare a conexiunii. Sistemul intră iar în starea 1, până la recepționarea unui alt mesaj, care îl pune în starea 6. Se decodează certificatul primit, datele binare sunt stocate în obiecte XByteSequence. Clientul a re-trimis nonce-ul semnat digital, iar pentru verificare se folosește cheia publică a clientului extrasă din certificat. Verificarea se face utilizând funcția DigitalSignatureCreator::veritfySignature(). Ca și în pasul anterior, la orice eroare de orice fel, se termină procesul. Pentru verificarea certificatului primit se folosește certificatul emitentului. Aici se citesc și permisiunile clientului, și în cazul în care acesta nu are privilegii pentru a accesa resursele serverului, se generează un mesaj de eroare, și se termină conexiunea. Dacă nonce-ul se potrivește cu cel salvat anterior, se generează cheia de sesiune, se criptează cu cheia secretă a clientului și este codificat cu Base64. Semnătura serverului este adăugat în mesaj, și este trimis clientului. Un alt mesaj cu numele utilizatorului și cheia generată se trimite serviciului de resurse. În acest pas, performanța de autentificare este citită și înscrisă în variabila mTime, pentru a fi citit la distrugerea obiectului. Sistemul trece în starea finală, și se distruge obiectul.
3.2.2. Serviciul de resurse
Structura și funcționarea acestui serviciu este foarte asemănătoare cu cel al serviciului de autentificare. Clasa XResService moștenește clasa XBaseService, iar la acceptarea unei noi conexiuni, se creează o instanță a clasei XResSvConnHandler, care moștenește clasa XISvConnHandler. Notificările sunt aceeași, singurul lucru care diferă este procesarea mesajelor.
Serviciul se ocupă de distribuirea fișierelor în directoarele partajate. Aceste directoare pot fi setate prin intermediul funcției setResourceDir() la cel mai înalt nivel, din API. Acesta va seta membrul m resDir, care va fi citit de fiecare solicitare a listei. Clientul poate cere lista cu fișiere, care va conține numele și calea fișierelor, cât și mărimea acestora.
Fiindcă aceste informații sunt trimise criptate, utilizatorii trebuie să se înregistreze înainte de a solicita orice date. Serviciul de autentificare trimite un mesaj intern, cu serviciul de resurse ca destinatar. Acest mesaj este trimis când un client se autentifică cu un certificat, și se generează o cheie secretă de sesiune. Mesajul va conține numele utilizatorului, și cheia generată, care odată recepționat de serviciul de resurse va fi stocat într-o structură de tip std::map. Orice cerere de informații va conține numele utilizatorului, astfel serviciul încarcă cheia și o va folosi pentru sesiunea curentă. Dacă numele utilizatorului este incorect, sau cheia nu se potrivește, mesajul nu va putea fi decriptat, și se va răspunde cu un mesaj de eroare.
Când se primește un mesaj care solicită lista de fișiere, serviciul va parcurge directoarele recursiv, formând răspunsul cu toate datele necesare. Dacă se cere un fișier, se verifică dacă se află în aceste directoare, și în caz afirmativ, se încarcă în memorie, într-un format std::vector<char>. În ambele cazuri datele sunt criptate și trimise clientului.
3.3. XClient
Partea de client a unui serviciu se creează moștenind clasa XBaseService [7], care oferă funcțiile callback necesare pentru a primi și trimite mesaje.
Funcționarea și structura sunt descrie în secțiunea anterioară. În Fig. 24 este prezentată diagrama de stare a clasei XClient. Constructorul componentei XClient are 2 parametrii, acestea fiind numele de utilizator și parola. Aceste date se vor folosi numai pentru identificarea utilizatorului de către client, pentru a încărca certificatul potrivit, iar în cazul în care aceste nu se găsește, informațiile vor fi folosite pentru a solicita un certificat. Datele private se pot schimba pe parcurs. XClient este controlat prin funcțiile din API-ul global. Majoritatea funcțiilor urmăresc stările prezentate în Fig. 25, adică se trimite solicitarea, se așteaptă un răspuns, și se generează rezultatul funcției, fie datele cerute, fie un mesaj de eroare. Unele proceduri se pot efectua fără conectarea la un server. Acestea sunt [12]:
getServerList(): Se generează și se trimite un mesaj către serviciul de autentificare a home serverului, care cere lista serverilor din rețea. După trimitere se așteaptă un răspuns de la server. Așteptarea răspunsului are un timeout de câteva secunde, dacă nu se primește se generează o eroare. Ultima eroare se salvează în variabila globală merrMsg. La recepționarea unui mesaj, se creează un std::vector care conține structuri cu informațiile serverilor.
switchUser(): Se folosește în cazul în care se dorește schimbarea utilizatorului. Dacă clientul a fost conectat la un server, acesta va fi deconectat. Practic se re-inițializează toate datele.
WriteFile(): Funcția scrie un buffer din memorie pe un dispozitiv de stocare fizic folosind funcția std::ofstream::write().
pingServer(): Simulează un ping, adică trimite un mesaj scurt serverului și măsoară timpul între trimitere și primire răspuns. Rezultatul va fi diferența între cele două timpuri.
getLastErrorMessageQ: Returnează conținutul variabilei m errMsg, care conține un mesaj care descrie ultima eroare raportată.
Connect(): Funcția ia ca parametru adresa serverului la care se dorește conexiunea, și o variabilă care va stoca timpul de conectare. Conectare în acest caz înseamnă autentificare, fie prin parolă, fie prin certificat. Se începe cu crearea directorului cu certificate și chei, dacă acesta nu există. Se verifică dacă există vreun certificat și cheie pe acest nume de utilizator. Dacă există, se începe verificarea validității cu ajutorul clasei CertificateChecker::VerifyCertificate(). În cazul în care certificatul sau cheia secretă nu sunt valide, se verifică certificatul home serverului. Dacă acesta nu este salvat local, se solicită de la server, și se așteaptă un răspuns. Dacă nu s-a primit nici un răspuns, se generează o eroare. Diagrama de stare este prezentată în Fig. 25. Odată având certificatul serverului în posesie, începe protocolul de autentificare. La sfârșitul cu succes al acestui protocol, clientul va avea un certificat valid. Acesta va fi stocat în variabila globală cert_X509, iar cheia secretă în variabila certsk. Aceste două obiecte vor fi scris în fișiere folosind funcțiile oferite de API-ul OpenSSL: PEM_write_PrivateKey și PEM_writePrivateKey. Având certificatul se contactează serviciul de resurse, și se primește o cheie de sesiune, conform protocolului descris anterior. Cheia este verificată la fiecare solicitare de resurse, iar dacă nu este valid, se generează o eroare, notificând utilizatorul că o reconectare este necesară.
Următoarele funcții se pot apela după autentificare la serverul de resurse:
getFileList(): Prima dată se verifică dacă utilizatorul este autentificat, și dacă are o cheie validă. Se solicită lista de fișiere după modelul prezentat în Fig. 25. Datele recepționate sunt decriptate, se parcurge lista, și se adaugă fișierele unul câte unul în vectorul specificat de client.
requestFile(): După verificarea cheii de sesiune, se creează un serviciu pe partea clientului, care se va conecta la server. Se solicită fișierul și se trece în stare de așteptare. Dacă se primește răspuns, se decriptează și se copiază conținutul fișierului în bufferul specificat de utilizator de tip std::vector<char>.
getCertificate(): La conectare la unul dintre serverele din rețea, certificatele sunt stocate în memorie și în fișiere. Aceste certificate sunt folosite automat, dar pentru le a afișa, se poate apela această funcție, care returnează unul dintre trei certificate într-o formă decodată. Se folosește o funcție OpenSSL X509_print() pentru a copia conținutul într-un șir de caractere care va fi returnat.
3.4. Implementarea API-ului
Interfața de programare oferă proiectarea unui sistem descris în această lucrare cu ușurință, prin interfața descrisă în secțiunea 3.3. Interfața grafică a clientului a fost creată cu ajutorul framework-ului Qt [23], implementând funcțiile din interfață pentru a crea serviciile și a interacționa cu serverul. În Fig. 26 se poate vedea o captură de ecran a interfeței de utilizator a clientului, după pornire, afișând lista cu servere, controale pentru reîmprospătare listă, verificare disponibilitate server și conectare.
După conectare se afișează lista cu fișiere disponibile și detalii despre acestea. Clientul permite salvarea fișierelor unul câte unul, salvarea tuturor fișierelor, sau doar deschiderea fișierelor suportate. Qt suportă mai multe tipuri de imagini, iar modulul Phonon suportă și clipuri video. Pentru a afișa certificatele folosite pentru această sesiune se navighează pe pagina ‘Certificates’, unde se pot solicita toate trei certificate. Pagina ‘Activity Log’ ține o evidență cu toate evenimentele din sesiunea curentă, iar navigând pe pagina ‘Switch User’, se poate schimba utilizatorul curent. Interfața grafică, cu lista de fișierele și o imagine deschisă se poate vedea în Fig. 27.
Serverul are doar interfață consolă, și afișează evenimentele importante, care includ: conectarea unui client, solicitările de către alți participanți, deconectarea clienților, etc. Serverul ține o evidență a tuturor clienților conectați și timpul de conectare a acestora într-un fișier local Interfața serverului se poate vedea în Fig. 28.
3.5. Rezultate experimentale
Testele au fost efectuate pe un calculator rulând sistemul de operare Windows XP SP3, procesor dual core cu frecvența 2800 MHz.
În Fig. 29 se văd timpii de autentificare pentru mai mulți clienți simultan. Timpul măsurat a fost intervalul dintre trimiterea cererii de autentificare până la recepționarea cheii de sesiune de la serverul de resurse. Se observă diferența între cele două autentificări, care este produsă de generarea certificatului și pașii adiționali pentru trimiterea acestuia. Dacă conectarea se face la un server liber, performanțele sunt bune, ajungând la 130 ms pentru autentificare fără certificat și 270 ms cu certificat. Performanța scade dacă mai mulți clienți se autentifică în același timp, ajungând la 607 / 1266 ms la 10 clienți simultan. Pentru a îmbunătății performanța unui server populat, se poate adăuga un alt server pentru a distribui autentificarea clienților.
În Fig. 30 se vede timpul de generare a cheilor RSA. Această operație necesită cele mai multe resurse ale procesorului. Generarea unei chei durează aproximativ 80 ms, ajungând la aproape 600 ms la 10 generări de chei în paralel. Fiindcă acest proces se bazează mai mult pe puterea de procesare a procesorului, cea mai evidentă metodă de a îmbunătății timpul de generare este de a folosi un procesor mai puternic. O alta metodă ar fi folosirea unui procesor dedicat doar pentru generare de chei, proiectat în special pentru această operație.
Timpul de autentificare este afectat și de starea serverului, adică dacă este inactiv, doar așteptând conexiuni, sau dacă se află in cursul procesării datelor. În Fig. 31 se vede diferența dintre aceste două stări. Serverul la care s-a măsurat autentificarea, criptează și transmite date la alți doi clienți deja conectați. Timpul de autentificarea în acest caz crește cu 10% în cazul autentificării fără generare certificat, și cu aproximativ 25% dacă se generează și certificat pentru client.
Pentru a analiza performanța autentificării, am măsurat fiecare pas al protocolului separat. Pe partea serverului, cum era de așteptat, generarea certificatului necesită cel mai mult timp de procesare, 45 ms. Cum s-a mai menționat acesta s-ar putea îmbunătății daca am folosi un dispozitiv dedicat pentru generarea cheilor. Generarea nonce-ului durează aproximativ 4 ms, ceea ce e acceptabil. Totuși pentru a genera numere aleatorii cât mai sigure, se poate înlocui si acesta cu un dispozitiv dedicat care generează nonce-uri. În Fig. 32 se pot vedea durata de execuție a fiecărui pas din protocol.
Pe partea clientului, protocoalele au un pas în plus, adică încărcarea certificatelor și a cheilor, ceea ce intră la categoria inițializare. Acesta necesită cel mai lung timp de completare, aproximativ 35 ms. Restul protocolului se desfășoară relativ într-un timp scurt. Aceste măsurători nu includ transportul de date, doar procesarea datelor. Protocolul descompus și durata de execuție a fiecărei pas se poate vedea în Fig. 33.
3.6. Concluzii la compartimentul 3.
Sistemul prezentat a fost proiectat pentru a oferi siguranța necesară pentru transportul datelor confidențiale într-un mediu nesecurizat, suportând pierderea mesajelor, generarea cheilor și a certificatelor. Canalele securizate sunt create pe linii de transmisiune normale, cu ajutorul celei mai avansate tehnici de criptografie, și prin folosirea protocoalelor de securitate re-proiectate. Protocoalele necesită multă putere de procesare, dar arhitectura distribuită a serviciilor garantează acesta.
Sistemul realizat a fost configurat și testat pentru rețelele de calculatoare ale firmei „Acasă la mama”, care deține o rețea de restaurante.
În perioada testării sistemului în timp real nu au fost semnalate oarecare probleme, sistemul lucrează în regim normal și fără deficiențe.
CONCLUZII GENERALE ȘI RECOMANDĂRI
Sistemul prezentat oferă dezvoltatorilor o interfață cu ajutorul cărei implementarea unei aplicații distribuite pe rețea se face cu ușurință. Sistemul a fost proiectat pentru a oferi siguranța necesară pentru transportul datelor confidențiale într-un mediu nesecurizat, suportând pierderea mesajelor, generarea cheilor și a certificatelor. Canalele securizate sunt create pe linii de transmisiune normale, cu ajutorul celei mai avansate tehnici de criptografie, și prin folosirea protocoalelor de securitate re-proiectate. Protocoalele necesită multă putere de procesare, dar arhitectura distribuită a serviciilor garantează acesta.
Arhitectura sistemului elimină serverul central de autentificare, înlocuindu-l cu serviciul de autentificare, care rulează pe fiecare server, distribuind astfel încărcarea. Înregistrarea utilizatorilor poate lua orice formă, oferind flexibilitate și mai multă securitate. Permisiunile utilizatorilor sunt disponibile fiecărui server la care se conectează, acesta având controlul asupra accesului la diferite resurse. Navigarea între serverele rețelei se face cu ușurință, acesta fiind meritul mecanismului Single Sign-On, care elimină necesitatea re-autentificării la fiecare furnizor de servicii, și a protocoalelor de securitate proiectate astfel încât aceste autentificări să se efectueze în cel mai scurt timp posibil, ajungând chiar și la timpuri de 100 ms. Distribuirea serviciilor de autentificare și de resurse permite scalarea sistemului cu ușurință, adaptându-se nevoilor utilizatorilor.
Platforma fiind dezvoltată după principiile ingineriei programării bazate pe componente este robustă, adaptabilă și ușor de actualizat. Orice componentă poate fi foarte ușor înlocuită cu o alta cu condiția ca interfața să nu se modifice sau dacă trebuie aduse modificări în funcționalitatea unei componente acestea se pot face cu un minim de efort. În plus componentele pot fi refolosite și la dezvoltarea altor sisteme. Componentele fiind încapsulate, adică structura internă este ascunsă și serviciile sunt oferite printr-o interfață bine definită, face ca programatorul să le poată integra mai ușor fără să știe cum funcționează acestea.
Noutatea platformei mele constă în folosirea componentelor XPCOM, care permite dezvoltarea aplicațiilor portabile. Folosind platforma Mozilla și API-ul NSPR pentru implementare, aplicațiile pot rula pe cele trei sisteme mari de operare existente: Microsoft Windows, Linux și Mac OS, dar și pe cele mobile, sau oricare unde Mozilla este disponibil.
Sistemul realizat a fost configurat și testat pentru rețelele de calculatoare ale firmei „Acasă la mama”, care deține o rețea de restaurante.
În perioada testării sistemului în timp real nu au fost semnalate oarecare probleme, sistemul lucrează în regim normal, fără deficiențe și urmează a fi discutat și eventual aprobat ca sistem de autentificare, autorizare și control al accesului la firma respectivă. În anexă (fugirile 34 – 44) sunt prezentate imagini cu diverse situații de lucru al acestui sistem în regim de lucru.
Soluția propusă pentru sistemul de autentificare este distribuită, dar totuși s-ar putea ivi probleme în cazul în care un număr mare de utilizatori vor să se conecteze în același timp. Pentru distribuirea autentificării se poate implementa în viitor un serviciu de balansare care să comunice cu fiecare server și să repartizeze clienții la serverele mai puțin încărcate, sporind astfel performanța sistemului. Alte îmbunătățiri ar fi implementarea unui serviciu de nume mai performant.
BIBLIOGRAFIE
Nica M., Tehnici de autentificare, http://itsecure.wordpress.com, 2007 (vizitat 15.03.2014).
Popa Sorin Eugen. Securitatea sistemelor informatice, Bacău, 2007. 136 p.
Thomas T., Primii pași în securitatea rețelelor, Corint, București, 2005. 415 p.
Abadi M., Needham R., Prudent Engineering Practice for Cryptographic Protocols, DEC SRC Research Report, 1994, pag. 1 – 22,.
AES Algorithm (Rijndael) Information, http://csrc.nist.gov/archive/aes/rijndael, 2001, (vizitat 25.02.2014).
Anderson R. Security Engineering: A Guide to Building Dependable Distributed Systems, NY 2001. 613 p.
Cisco Systems, 2010 http://www.cisco.com/support/RU/ (vizitat 21.04.2014).
Cisco Systems, User Guide for Cisco Secure Access Control System 5.4, Cisco Systems, Inc, 2012. 682 p.
Genge B., Ignat I., Verifying the independence of security protocols, pag. 155-163. s.l.:, IEEE International Conference on Intelligent Computer Comumunication and Processings, 2007.
Gerck E., Overview of Certification Systems: X.509, PKIX, CA, PGP and SKIP, The Bell, 1(3):8, July 2000.
Guttman, Joshua D., Security Protocol Design Via Authentication Tests. s.l.: In Proceedings of the 15th IEEE Computer Security Foundations Workshop, IEEE CS Press, 2002.
Hunter L., Active Directory User Guide, Springer-Verlag, 2005. 352 p.
Josefsson S., The Base16, Base32, and Base64 Data Encodings, octombrie 2006 http://tools.ietf.org/html/rfc4648 (vizitat 18.04.2014)..
Joshua D. Guttman, F. Javier Thayer Fabrega, Authentication tests and the structure of bundles, Theoretical Computer Science, Vol. 283, No. 2, 2002. pp. 333-380.
Kaufman, C., Distributed Authentication Security Service (DASS).
http://tools.ietf.org/html/rfc1507 (vizitat 15. 02. 2014).
Killpack R., eDirectory Field Guide, Springer-Verlag, 2006. 304 p.
Lampson B., M. Abadi, M. Burrows, E. Wobber. Authentication in Distributed Systems: Theory and Practice. s.l. : ACM Trans. Computer Systems 10, 1992. pp. 265-310.
Menezes A., van Oorschot P., Vanstone S., Handbook of Applied Cryptography, CRC Press, 1996. 816 p.
Mozilla Corporation, XPCOM, Cross Platform Component Model, https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM, 2013 (vizitat 18. 03. 2014).
OpenLDAP, versiunea 2.4.15., http://www.openldap.org/, 2008 (vizitat 15. 02. 2014).
Pashalidis A., Mitchell C. J., A Taxonomy of Single Sign-On Systems, Volume 2727/2003. s.l. : Springer Berlin / Heidelberg, 2003.
Project, OpenSSL., available at http://www.openssl.org/ , 2008. (vizitat 17. 02. 2014).
Qt, versiunea 4.5, http://www.qtsoftware.com/products , 2009. (vizitat 17. 02. 2014).
Stallings W., Cryptography and Network Security, 4th edition, Prentice Hall. ISBN 0-13-187319-3., 2005. 900 p.
Cisco Systems, Inc., Пример конфигурации мультидоменной аутентификации IEEE 802.1x для коммутаторов Cisco Catalyst уровня 3 с фиксированной конфигурацией. http://www.smbtelecom.ru/Documentation (vizitat 19. 04. 2014).
Гладких А.А., Дементьев В.Е.. Базовые принципы информационной безопасности вычислительных сетей. Ульяновск: УлГТУ, 2009. 156 стр.
Глухих В.И. Информационная безопасность и защита данных. Иркутск: Изд-во ИГТУ, 2011. 250 стр.
Идлис А., Cеть широкополосного доступа: решение задачи, Часть 2: Подключаем абонента. Протокол доступа и режим работы абонентского устройства, «Теле-Cпутник», 2010, http://www.telesputnik.ru/archive/pdf/178/58.pdf (vizitat 03.03.2014).
Смит Р. Аутентификация: от паролей до открытых ключей, М.: Вильямс, 2002. 432 стр.
Федотов А. М. Информационная безопасность в корпоративной сети/ Проблемы безопасности и чрезвычайных ситуаций, М.: ВИНИТИ, 2008. nr.2. стр. 88-101. http://elib.sbras.ru:8080/jspui/bitstream/SBRAS/1760/6/IT_Security.pdf (vizitat 03.03.2014).
Шелупанов А. И др., Аутентификация. Теория и практика обеспечения доступа к информационным ресурсам. М.: Горячая линия – Телеком, 2009. 552 стр.
ANEXĂ
Fig. 1 – Modul de funcționare a semnăturii digitale
Fig. 2. Certificat X.509
Fig. 3. Arhitectura simplificatăa platformei Mozilla
Fig. 4. Arhitectura sistemului
Fig. 5. Pașii de execuție pentru mecanismul Single Sign-on
Fig. 6. Componentele sistemului
Fig. 7. Structura internă al serviciului de autentificare
Fig. 8. Inițializarea modulului XServer
Fig. 9. Diagrama de secvență a autentificării unui client
Fig. 10. Structura internă a componentei XClient
Fig. 11 – Structura bazei de date
Fig. 12. Protocolul complet de autentificare
Fig. 13 – Clasa XThread
Fig. 14 – Clasa XTCPSocket
Fig. 15. Diagrama de clase pentru clasele: XMessage, XSimpleParser, XSimpleList și XBase64Coder
Fig. 16 – Diagrama de clase – OpenSSL
Fig. 17 – Diagrama de clase a canalelor de comunicație
Fig. 18 – Diagrama de clase a serviciilor
Fig. 19 – Clasele de comunicație și relațiile între ele
Fig. 20 – Diagrama de stare a sistemului de servicii
Fig. 21 – Diagrama de stare a sistemului de conexiuni
Fig. 22 – Diagrama de stare a execuției serviciului de autentificare
Fig. 23 – Diagrama de stare a execuției serviciului de resurse
Fig. 24 – Diagrama de stare: XClient
Fig. 25 – Diagrama de stare a execuției cererilor de tip request-response
Fig. 26 – GUI client: Lista cu servere
Fig. 27 – GUI client: lista cu fișiere
Fig. 28 – Interfața consolă a serverului
Fig. 29 – Timp de autentificare cu și fără generare de certificat
Fig. 30 – Timp de generare a cheilor RSA
Fig. 31 – Timpul de autentificare la un server activ
Fig. 32 – Timpul de execuție a protocoalelor pe partea serverului
Fig. 33 – Timpul de execuție a protocoalelor pe partea clientului
Fig. 34 – Deschiderea unei noi conexiuni remotedesktop
Fig. 35 – Accesul la windows server (pe server sunt creați mai mulți useri)
Fig. 36 – Deschiderea paginii de desktop pe server
Fig. 37 – Deschiderea ferestrei de acces în sistemul de conturi
Fig. 38 – Sistemul propriu zis de conturi
Fig. 39 – Opțiunile pe care le are Administratorul de bază
Fig. 40 – Numărul de utilizatori ai sistemului de conturi
Fig. 41 – Detalii despre program
Fig. 42 – Detalii despre program
Fig. 43 – Detalii despre program
Fig. 44 – Fereastra pe pagina chelnerului
BIBLIOGRAFIE
Nica M., Tehnici de autentificare, http://itsecure.wordpress.com, 2007 (vizitat 15.03.2014).
Popa Sorin Eugen. Securitatea sistemelor informatice, Bacău, 2007. 136 p.
Thomas T., Primii pași în securitatea rețelelor, Corint, București, 2005. 415 p.
Abadi M., Needham R., Prudent Engineering Practice for Cryptographic Protocols, DEC SRC Research Report, 1994, pag. 1 – 22,.
AES Algorithm (Rijndael) Information, http://csrc.nist.gov/archive/aes/rijndael, 2001, (vizitat 25.02.2014).
Anderson R. Security Engineering: A Guide to Building Dependable Distributed Systems, NY 2001. 613 p.
Cisco Systems, 2010 http://www.cisco.com/support/RU/ (vizitat 21.04.2014).
Cisco Systems, User Guide for Cisco Secure Access Control System 5.4, Cisco Systems, Inc, 2012. 682 p.
Genge B., Ignat I., Verifying the independence of security protocols, pag. 155-163. s.l.:, IEEE International Conference on Intelligent Computer Comumunication and Processings, 2007.
Gerck E., Overview of Certification Systems: X.509, PKIX, CA, PGP and SKIP, The Bell, 1(3):8, July 2000.
Guttman, Joshua D., Security Protocol Design Via Authentication Tests. s.l.: In Proceedings of the 15th IEEE Computer Security Foundations Workshop, IEEE CS Press, 2002.
Hunter L., Active Directory User Guide, Springer-Verlag, 2005. 352 p.
Josefsson S., The Base16, Base32, and Base64 Data Encodings, octombrie 2006 http://tools.ietf.org/html/rfc4648 (vizitat 18.04.2014)..
Joshua D. Guttman, F. Javier Thayer Fabrega, Authentication tests and the structure of bundles, Theoretical Computer Science, Vol. 283, No. 2, 2002. pp. 333-380.
Kaufman, C., Distributed Authentication Security Service (DASS).
http://tools.ietf.org/html/rfc1507 (vizitat 15. 02. 2014).
Killpack R., eDirectory Field Guide, Springer-Verlag, 2006. 304 p.
Lampson B., M. Abadi, M. Burrows, E. Wobber. Authentication in Distributed Systems: Theory and Practice. s.l. : ACM Trans. Computer Systems 10, 1992. pp. 265-310.
Menezes A., van Oorschot P., Vanstone S., Handbook of Applied Cryptography, CRC Press, 1996. 816 p.
Mozilla Corporation, XPCOM, Cross Platform Component Model, https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM, 2013 (vizitat 18. 03. 2014).
OpenLDAP, versiunea 2.4.15., http://www.openldap.org/, 2008 (vizitat 15. 02. 2014).
Pashalidis A., Mitchell C. J., A Taxonomy of Single Sign-On Systems, Volume 2727/2003. s.l. : Springer Berlin / Heidelberg, 2003.
Project, OpenSSL., available at http://www.openssl.org/ , 2008. (vizitat 17. 02. 2014).
Qt, versiunea 4.5, http://www.qtsoftware.com/products , 2009. (vizitat 17. 02. 2014).
Stallings W., Cryptography and Network Security, 4th edition, Prentice Hall. ISBN 0-13-187319-3., 2005. 900 p.
Cisco Systems, Inc., Пример конфигурации мультидоменной аутентификации IEEE 802.1x для коммутаторов Cisco Catalyst уровня 3 с фиксированной конфигурацией. http://www.smbtelecom.ru/Documentation (vizitat 19. 04. 2014).
Гладких А.А., Дементьев В.Е.. Базовые принципы информационной безопасности вычислительных сетей. Ульяновск: УлГТУ, 2009. 156 стр.
Глухих В.И. Информационная безопасность и защита данных. Иркутск: Изд-во ИГТУ, 2011. 250 стр.
Идлис А., Cеть широкополосного доступа: решение задачи, Часть 2: Подключаем абонента. Протокол доступа и режим работы абонентского устройства, «Теле-Cпутник», 2010, http://www.telesputnik.ru/archive/pdf/178/58.pdf (vizitat 03.03.2014).
Смит Р. Аутентификация: от паролей до открытых ключей, М.: Вильямс, 2002. 432 стр.
Федотов А. М. Информационная безопасность в корпоративной сети/ Проблемы безопасности и чрезвычайных ситуаций, М.: ВИНИТИ, 2008. nr.2. стр. 88-101. http://elib.sbras.ru:8080/jspui/bitstream/SBRAS/1760/6/IT_Security.pdf (vizitat 03.03.2014).
Шелупанов А. И др., Аутентификация. Теория и практика обеспечения доступа к информационным ресурсам. М.: Горячая линия – Телеком, 2009. 552 стр.
ANEXĂ
Fig. 1 – Modul de funcționare a semnăturii digitale
Fig. 2. Certificat X.509
Fig. 3. Arhitectura simplificatăa platformei Mozilla
Fig. 4. Arhitectura sistemului
Fig. 5. Pașii de execuție pentru mecanismul Single Sign-on
Fig. 6. Componentele sistemului
Fig. 7. Structura internă al serviciului de autentificare
Fig. 8. Inițializarea modulului XServer
Fig. 9. Diagrama de secvență a autentificării unui client
Fig. 10. Structura internă a componentei XClient
Fig. 11 – Structura bazei de date
Fig. 12. Protocolul complet de autentificare
Fig. 13 – Clasa XThread
Fig. 14 – Clasa XTCPSocket
Fig. 15. Diagrama de clase pentru clasele: XMessage, XSimpleParser, XSimpleList și XBase64Coder
Fig. 16 – Diagrama de clase – OpenSSL
Fig. 17 – Diagrama de clase a canalelor de comunicație
Fig. 18 – Diagrama de clase a serviciilor
Fig. 19 – Clasele de comunicație și relațiile între ele
Fig. 20 – Diagrama de stare a sistemului de servicii
Fig. 21 – Diagrama de stare a sistemului de conexiuni
Fig. 22 – Diagrama de stare a execuției serviciului de autentificare
Fig. 23 – Diagrama de stare a execuției serviciului de resurse
Fig. 24 – Diagrama de stare: XClient
Fig. 25 – Diagrama de stare a execuției cererilor de tip request-response
Fig. 26 – GUI client: Lista cu servere
Fig. 27 – GUI client: lista cu fișiere
Fig. 28 – Interfața consolă a serverului
Fig. 29 – Timp de autentificare cu și fără generare de certificat
Fig. 30 – Timp de generare a cheilor RSA
Fig. 31 – Timpul de autentificare la un server activ
Fig. 32 – Timpul de execuție a protocoalelor pe partea serverului
Fig. 33 – Timpul de execuție a protocoalelor pe partea clientului
Fig. 34 – Deschiderea unei noi conexiuni remotedesktop
Fig. 35 – Accesul la windows server (pe server sunt creați mai mulți useri)
Fig. 36 – Deschiderea paginii de desktop pe server
Fig. 37 – Deschiderea ferestrei de acces în sistemul de conturi
Fig. 38 – Sistemul propriu zis de conturi
Fig. 39 – Opțiunile pe care le are Administratorul de bază
Fig. 40 – Numărul de utilizatori ai sistemului de conturi
Fig. 41 – Detalii despre program
Fig. 42 – Detalii despre program
Fig. 43 – Detalii despre program
Fig. 44 – Fereastra pe pagina chelnerului
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Sistem de Autentificare, Autorizare Si Control al Accesului In Sistemele Distribuite (ID: 163488)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
