Sunteți pe pagina 1din 67

11

 Autentificare e
procesorul prin care
este identificat un
utilizator.
 Autorizarea este
procesul prin care un
utilizator primeste
accesul la o resursa.
 <exemplu>
 Clasa WindowsIdentity reprezinta un utilizator
Windows.
 Ofera acces la numele utilizatorului, tipul
autentificarii, etc.
 Nu face autentificare. Aceasta a fost deja facuta
de Windows.
 Puteti crea o instanta a WindowsIdentity folosind
una din metodele:
 GetAnonymous: Returneaza un WindowsIdentity ce
contine un user neautentificat. Puteti folosii un astfel
de WindowsIdentity pentru a verifica daca aplicatia
voastra poate functiona si cu user neautentificat.
 GetCurrent: Returneaza un WindowsIdentity ce
contine userul actual.
 Impersonate: Returneaza un WindowsIdentity ce
contine un user existent pe sistem.
 WindowsIdentity contine:
 AuthentificationType: un string ce contine tipul
autentificarii (de obicei NTLM)
 IsAnonymous
 IsAuthentificated
 IsGuest
 IsSystem
 Name
 Token
 Folositi
WindowsIdentity
pentru a
determina care
este userul actual
si daca este
autenetificat
pentru a’i da sau
nu acces la
portiuni de cod.
 Clasa WindowsPrincipal reprezinta un grup de utilizatori windows.
 Puteti crea un WindowsPrincipal in 2 moduri:
 Din un WindowsIdentity
 Puteti extrage WindowsPrincipal-ul din threadul care ruleaza in aplicatie.
 Pentru a verifica ce rol au membrii grupului din WindowsPrincipal folosind
metoda IsInRole.
 Metoda IsInRole poate primii ca parametru:
 Un membru al enumerarii WindowsBuiltInRole
 Un string in formatul “DOMENIU sau NUME_COMPUTER\Nume grup”
 Daca nu stiti care este numele calculatorului sau domeniul puteti folosii
System.Environment.MachineName respectiv
System.Environment.UserDomainName.
 Clasa PrincipalPermission si PrincipalPermissionAttribute pot fi folosite
pentru a face verificari CAS atat cand folositi securitate declarativa cat si
imperativa. Puteti solicita astfel ca un user sa fie autentificat, sa aiba un
anumit nume sau aiba un anumit rol.
 Proprietatile din un PrincipalPermission sunt urmatoarele:
 Authetificated
 Name
 Role
 Vom folosii metoda Demand pentru a verifica daca principalul curent
respecta anumite cerinte. In caz contrar va fi aruncata exceptie.
 Folosind RBS declarativ instruiti runtime-ul sa permita
executarea unei metode sau lansarea in executie a unui
assembly numai daca utlizatorul ce ruleaza acea
metoda/assembly este in un anumit rol, este autentificat
si/sau are un anumite username.
 Pentru a folosii RBS trebuie sa aveti 3 elemente in cod:
 Un apel la
System.AppDomain.CurrentDomain.SetPrincipalPolicy in care
sa specificati politica de securitate (ex. Windows Princial)
 un bloc try/catch in care sa prindeti accesuri neautorizate
 un atribut PrincialPermission in care sa specificati cerintele de
acces la metoda
 Folosint RBS imperativ puteti autoriza accesul la
bucati de cod din interiorul unei metode.
 Veti folosii permisia PrincipalPermission.
 Ca la RBS declarativ exista 3 cerinte:
 Un apel la
System.AppDomain.CurrentDomain.SetPrincipalPolicy in
care sa specificati politica de securitate (ex. Windows
Princial)
 un bloc try/catch in care sa prindeti accesuri neautorizate
 un obiect PrincialPermission in care sa specificati cerintele
de acces la metoda
 Primele 2 elemente sunt exact ca la RBS
imperativ.
 Obiectul PrincipalPermission are 3 constructori:
 PrincipalPermission(PermissionState)
 PrincipalPermission(Name, Role)
 PrincipalPermission(Name, Role, Authenticated)
 Atunci cand doriti sa autentificati useri folosind o baza de date proprie veti
implementa interfata IIdentity si IPrincipal.
 Puteti astfel sa va creati propriul Identity care sa includa atributele custom si
propriul Principal ce va implementa ierarhia proprie.
 Clase ce implementeaza IIdentity sunt:
 WindowsIdentity
 FormsIdentity
 PassportIdentity
 GenericIdentity
 Pentru a implementa IIdentity trebuie implementate proprietatile:
 AuthentificationType: un string ce determina modul de autentificare al userului. Puteti
verifica astfel daca aveti incredere in modul in care s-a realizat autentificarea.
 IsAuthenticard: un bool prin care aflati daca userul s-a autentificat.
 Name: un string ce contine username-ul. Acesta trebuie sa fie identifice in mod unic
contul utilizatorului si aceasta proprietate trebuie implementata chiar daca mecanismul
de autentificare nu foloseste username-uri.
 Pentru a implemente IPrincipal trebuie implementat un
constructor, o proprietate si o metoda .
 Constructorul accepta un obiect IIdentity si un array de string-uri
ce contin rolurile. Puteti adauga supraincarcari.
 Proprietatea implementeaza IPrincipal.Identity care ar trebuii sa
intoarca identitatea obiectului. (IIdentity)
 Metoda este IsInRole care primeste ca parametru un singur
string (rolul ce va fi verificat) si intoare true daca rolul este
verificat.
 Puteti face si urmatoarele:
 Adaugati o proprietare Roles care sa intoarca rolurile disponibile
 Adaugati o metoda IsInAllRoles care sa verifice daca prinpal-ul este in
toate rolurile, etc.
 Daca nu doriti sa implementati IPrincipal si IIdentity
poteti folosii clasele GenericPrincipal si GenericIdentity.
 Acestea ofera implementarea minimia a IPrincipal
respectiv IIdentity.
 GenericIdentity are 2 constructori: unul cu username si al
doilea cu username si tipul de autentificare.
 Nu puteti schimba valorile. Trebuie precizate in
constructor.
 GenericPrincipal are un singur constructor care necesita
atat un GenericIdentity cat si un array de string-uri cu
rolurile pe care le poate avea userul.
 Trebuie urmati urmatorii
pasi:
 Creati un obiect
GenericIdentity sau alt obiect
care implementeaza IIdentity
 Creati un obiect
GenericPrincipal sau alt obiect
care implementeaza IPrincipal
 Setati priprietatea
Thread.CurrentPrincipal cu
obiectul Principal definit
anterior.
 Folositi securitatea RBS
declarativa sau imperativa.
 Atunci cand va incercati sa va autentificati la un
la un stream Security.NegociateStream sau
Security.SslStream, daca autentificare nu s-a
facut vor fi aruncate exceptii:
 System.Security.Authentication.AuthenticationExcep
tion
 System.Security.Authentication.AuthenticationExcep
tion
 Sistemele de operare folosesc ACL-uri pentru a
da acces la fisiere, directoare, imprimante,
serivicii si cam la orice resursa.
 Ca dezvoltator puteti folosii ACL-urile si pentru:
 A da acces utilizatorilor la resurse de sistem de
operare la care altfel nu ar avea acces.
 A restrictiona accesul utilizatorilor la resursele
sistemului de operare.
 O Discretionary Access Control List (DACL) este un
mecanism de autentificare daca identifica daca
utilizatori sau grupuri de utilizatori au acces la un obiect.
 Windows tine prinvilegiile pe care le au utilizatorii la
accesul resurselor in DACL-uri.
 Daca un DACL nu identifica explicit un grup sau un
utilizator (din care face parte userul) atunci acel user nu
va fi autentificat.
 In general DACL-urile sunt controlate de creatorul
obiectului (sau de detinatorul acestuia) si contin mai
multe ACE-uri (acces controle entries).
 Cand asignati o DACL unui obiect creati permisii
explicite acelui obiect.
 Totusi asignarea manuala a permisiilor pentru
fiecare obiect necesita mult timp si effort.
 Din acest motiv majoritatea obiectelor au numai
permisii mostenite.
 Permisiile mostenite propaga permisiile unui obiect
de la parintele sau.
 De exemplu: cand creati un director pe diskul C:
acesta va avea initial permisiile disk-ului C:.
 Permisiile in windows sunt cumulative:
 Maria este membru al grupului Accounting si Management.
 prin DACL-uri
 Maria are acces de citire explicit la un fisier
 Grupul Accounting are acces de scriere la acel fisier.
 Grupul Management are Full Control pe acel fisier.
 Maria va avea Full Control pe acel fisier.
 DAR: deny este mai puternic decat grant.
 Daca grupul Accounding avea deny la scriere acel fisier nici Maria
nu putea sa scrie in fisierul respectiv.
 Daca in DACL-uri nu exista nici o intrare (ACE) pentru
Maria aceasta nu avea acces.
 Permisii diferite au proprietati diferite. De exemplu fiseriele si
registry-ul au permisii Full Control si Delete in timp ce Execute
este unic pentru fisiere.
 In .NET framework putem folosii enumerarea FileSystemRights
pentru a specifica permisiile unui fisier sau director.
 Cateva din membrii FileSystemRights sunt:
 FullControl
 Modify
 ReadAndExecute
 ListDirectory
 Read
 Write
 SACL reprezinta un mecanism prin care puteti
verifica existenta unei anumite permisii.
 In timp ce DACL restrictioneaza accesul SACL
verifica daca acesta exista.
 SACL pot fii folosite pentru a inregistra intrari in log-
ul de securitate a systemului, pentru a determina
daca s-a incercat vreo intruziune sau daca o aplicatie
are permisii destule pentru a rula bine.
 Un dezvoltator poate folosii SALC pentru a verifica
daca aplicatia scrisa ruleaza bine in medii cu
securitate mare.
 In mod normal windows-ul nu log-eaza event-uri
SACL (de auditare) chiar daca folositi SACL in
aplicatie.
 Pentru a folosii SACL urmati urmatorii pasi:
 Deschideti Local Security Policy din Administrative Tools.
 Expandati Local Policies si apoi click pe Audit Policy.
 In panel-ul din dreapta intrati pe Audit Object Access si
selectati Failere pentru a loga event-urile de insucces si
Succes pentru a loga event-urile de succes.
 Namespace-ul System.Security.AccessControl contine toate
clase pentru folosit ACL-uri in .NET.
 Pentru fiecare resursa din OS namespace-ul contine 3 clase:
 <Tip>Security: Contine metode pentru a citii o colectie de DACL-uri
(GetAccessRules) sau SACL-uri (GetAuditRules), si de adaugare DACL-
uri si SACL-uri (AddAccessRule, RemoveAccessRule respectiv
AddAuditRule si RemoveAuditRule). Clasele mostenesc
NativeObjectSecurity.
 <Tip>AccessRule: Reprezinta un set de drepturi de acces pentru un
utilizator sau grup. Clasa mosteneste AccessRule, care la randul ei
mosteneste AuthorizationRule.
 <Tip>AuditRule: Reprezinta un set de drepturi de acces ce vor fi
audiate pentru un utilizator sau grup. Clasa mosteneste AuditRule, care
la randul ei mosteneste AuthorizationRule.
 Puteti urma urmatorii pasi:
 Instantiati o clasa ce mosteneste NativeObjectSecurity (ex:
DirectorySecurity, FileSecurity, RegistrySecurity sau
MutexSecurity). Multe clase din namespace-ul
Microsoft.Win32 contine metode GetAccessControl ce
creaza astfel de obiecte.
 Apelati metoda GetAccessRules pentru a crea o instanta a
AuthorizationRuleCollection.
 Iterati prin AuthorizationRuleCollection pentru a analiza
fiecare ACL in parte.
 Puteti folosii GetAuditRules in loc de GetAccessRules pt
SACL.
 Puteti urma urmatorii pasi:
 Apelati metoda GetAccessControl pentru a instantia o metota
de mosteneste NativeObject Security ex: DirectorySecurity,
FileSecurity, RegistrySecurity sau MutexSecurity).
 Adaugati sau stergeti ACE-uri din acel ACL. In mod normal veti
crea un ACE din un user (sau group) name, o enumerare in care
specifica dreptul (de ex FileSystemRights) si o enumerare
AccessControlType in care specificati daca permiteti sau
interziceti acces acces.
 Apelati metoda SetAccessControl pentru a aplica schimbarile.
 In general criptarea de date se face dupa o anumita
cheie de criptare.
 In cazul cheilor simetrice se va folosii aceasi cheie
atat pentru criptarea datelor cat si pentru
decriptarea lor.
 Algoritmii de criptare simetrica proceseaza text cu
cheia secreta de encriptie pentru a encripta datele.
 Textul criptat nu poate fi decriptat usor fara cheia
simetrica
 Avantaje:
 Algoritmii simetrici sunt foarte rapizi si sunt potriviti pentru
cantitati mari de date.
 Dezavantaje:
 Un atacator poate folosii o tehnica brute force pentru a incerca
toate variantele de cheie simetrica. Un algoritm simetric simplu
ar necesita cel putin 2^56 incercari.
 Criptarea simetrica necesita schimbul cheii. Atat cel care
cripteaza cat si cel care decripteaza trebuie sa intra in posesia
cheii simetrice.
 Trebuie gasite o cale sigura de transmitere chei simetrice. Un
exemplu este transmiterea prin posta  a cheii de securitate.
 Este recomandat ca cheile sa fie schimbate periodic
 Algoritmi de criptare din .NET Framework
 RijndaelManaged
 Cheie de lungime de la 128bit la 256bit in incremente de 32biti
 Implementare a algoritmului Rijndael in .NET
 Algoritm cunoscut si sub numele Advanced Encryption Standard
(AES)
 Este singurul algoritm din .NET implementat complet managed deci
poate fi folosit in medii partially trusted.
 DES
 Data Encryption Standard
 Cheie de lungiem 56biti
 Este vulnerabil la atacuri dar ramane folosit in multe platforme
legacy.
 Algoritmi de criptare din .NET Framework
 RC2
 Cheie de lungime variabila
 DES cu lungime variabila.
 TripleDES
 Cheie de lungime 156biti din care 112 biti utilizati utilizati
efectiv pentru encriptie
 Aplica algoritmul DES de 3 ori
 Toti algoritmii simetrici deriva din clasa
System.Security.Cryptography.SymetricAlgorthm, si au
urmatoarele proprietati:
 BlockSize: Numarul de biti pe care algoritmul ii proceseaza o data. In
general il puteti ignora.
 FeedbackSize: Un aspect al algoritmului de encriptie. In general il
puteti ignora.
 IV: Vectorul de initializare. Trebuie sa fie acelasi la criptare si la
decriptare. Este folosit pentru a ascunde si mai bine primul block de
date ca este encriptate.
 Key: Cheia de criptare/decriptare.
 KeySize: Marimea cheii in biti. La creare runtime-ul selecteaza cea mai
mare cheie suportate de algoritm. Puteti sa modificati marimea daca
decriptorul nu suporta marimea maxima.
 LegalBlockSizes: Marimile acceptate de algoritm pe
blockuri (in biti).
 LegalKeySizes: Marimile acceptate de algoritm pt chei (in
biti).
 Mode: Un aspect al procesului de decriptate. Setat la un
membru al enumerarii CipherMode, in general Cipher Block
Chaining (CBC).
 Padding: Un membru al enumerarii PaddingMode.
Reprezinta modul in care algoritmul de encriptie
completeza orice diferenta intra block size si marimea
textului de encriptat.
 Toti algoritmii simetrici deriva din clasa
System.Security.Cryptography.SymetricAlgorthm, si
au urmatoarele metode:
 CreateDecryptor: Creaza un obiect de tip ICryptoTransform
ce poate fi folosit de un CrypoStream pt decriptare.
 CreateEncryptor: Folosit pt criptare.
 GenerateIV: Genereaza aleator un vector de initializare.
 GenerateKey: Genereaza o cheie de criptare aleator.
 ValidKeySize: Determina daca marimea specificata pentru
cheie este valida si intoarce un bool.
 Inainte de a se putea face criptare si decriptarea de date
atat cel ce cripteaza cat si cel care decripteaza trebuie sa
intre in posesia unei chei comune de criptare/decriptare.
 Nu puteti folosii orice text normal. Cheile de secrurite au
o lungime fixa deci nu puteti seta direct la Key o parola
scrisa de cineva.
 Puteti folosii clasa Cryptography.Rfc2898DeriveBytes
pentru a genera o cheie de securitate din un text.
 Exista si clasa PasswordDeriveBytes care va ofera si
posibilitatea de schimbare a algoritmului de hash.
 Rfc2898DeriveBytes primeste 3 parametrii in afara de parola utilizatorului:
 O valoare salt
 Un vector de initializare
 Numarul de iteratii folosite pentru a genera cheia
 Orice schimbare in acesti parametrii trebuie facut atat la cel ce cripteaza cat si la
cel ce decritpeaza.
 Cea mai simpla modalitate de a seta aceste valori e de a le trimite in constructor la
Rfc2898DeriveBytes, si apoi de a folosii metoda GetBytes.
 Metoda GetBytes primeste un integer, ce reprezinta numarul de bytes pe care
trebuie sa ii aiba cheia de securitate. Atunci cand determinati o cheie de securitate
folosind Rfc2898DeriveBytes veti determina numarul de bytes functie de
KeySize.
 Algoritmii de criptare trebuie sa aiba si acelasi IV. Daca tot ce se schimba intre
partenerii de comunicatie este o parola atunci este recomandat sa generati IV-ul
din aceasta parola.
 Daca lungimea cheii de securitate este determinta functie de KeySize, lungimea
IV-ului e determinata functie de BlockSize.
Stabilirea unei chei simetrice
 Pasii ce trebuie urmati pentru criptare sau decriptare
folosind chei simetrice sunt:
 Creati un obiect Stream pentru memoria sau fisierul din care
cititi.
 Creati un obiect SymmetricAlgorithm.
 Specificati cheia sau IV-ul (sau amandoua).
 Creati un obiect ICryptoTransform , apeland metoda
SymmetricAlgorithm.CreateEncryptor() , respectiv
SymmetricAlgorithm.CreateDecryptor().
 Creati un CryptoStream folosind obiectul Stream si obiectul
ICryptoTransform.
 Scrieti sau cititi din obiectul CryptoStream, exact ca dintru-ul
stream normal.
 Criptarea asimetrica foloseste o cheie pentru a cripta si o
cheie pentru a decripta datele.
 Chaia de criptare se numeste cheie publica si cea de
decriptare cheie privata.
 Mesajele criptate cu cheia publica pot fi decriptate
numai cu cheia privata.
 Procesul de criptare cu cheie asimetrica incepe cu
schimbul de chei publice. Dupa ce acest schimb s-a facut
criptarea se va face cu cheia publica.
 Aceste comunicatii nu pot fi decriptate decat de cei care
au cheia privata de decriptare.
 Avantaje:
 Algoritmii de criptare cu chei asimetrice sunt in general mult mai greu
de spart decat cei cu chei simetrice.
 Dezavantaje:
 Criptarea si decritarea functioneaza mult mai greu. Din acest motiv nu
se recomanda folosirea pentru cantitati mari de date.
 O tehnica des folosita este transferul cheii de criptare simetrica
folosind criptare asimetrica.
 O alta diferenta intre simetric si asimetric este management-ul
cheilor. In general organizatiile implementeaza o PKI (public key
infrastructure), cum este Certificate Services din Win2003
Server. PKI este responsabila cu distribuirea, gestionarea si
revocarea certificatelor de securitate in organizatie.
 Toti algoritmii asimetrici in .NET implementeaza
clasa Cryptography.AsymmetricAlgorithm.
 Aceasta are urmatoarele proprietati:
 KeyExchangeAlgorithm: Numele algoritmului de schimb al
cheii. In general nu trebuie sa modificati aici.
 KeySize: Marimea cheii private de securitate in biti.
 LegalKeySizes
 SignatureAlgorithm: URL-ul unui fisier XML care descrie
algoritmul de semnare. In general nu trebuie sa modificati
aici.
 Spre deosebire de SymmetricAlgorithm, AsymmetricAlgorithm nu are
metode, functionalitatea fiind inclusa in obiectele care implementeaza
AsymmetricAlgorithm:
 RSACryptoServiceProvider: implementare a algoritmului RSA
 DSACryptoServiceProvider: pentru semnarea digitala a mesajelor.
 In afara de proprietatile mostenite din AsymmetricAlgorithm,
RSACryptoServiceProvider are urmatorele proprietati:
 PersistKeyInCsp: valoare booleana. True daca doriti sa salvati cheia in
CSP. Setati TRUE atunci cand doriti sa refolositi cheia fara a o exporta.
 UseMachineKeyStore: valoare booleana. Setati true atunci cand doriti
sa salvati cheia in store-ul computerlui, in loc de cel al userului.
 RSACryptoServiceProvider include urmatoarele
metode:
 Decrypt
 Encrypt
 ExportParameters
 FromXmlString
 ImportParameters
 SignData
 SignHash
 VerifyData
 VerifyHash
 Cheile RSA sunt mai complexe decat cele simetrice.
 Cheile RSA se numesc parametrii si sunt reprezentati de
structura RSAParameters.
 O structura RSAParameters contine urmatorii membrii:
 D: Cheia privata
 Exponent: (cunoscut si ca e) Partea scurta a cheii publice
 Modulus: (cunoscut si ca n) Partea lunga a cheii publice
 Pentru a exporta cheia publica aplelati metoda
ExportParameters cu false. Pentru a exporta ambele chei apelati
cu true.
 Puteti exporta cheile de securitate si in format XML
cu metoda ToXmlString. Parametrii de apel ai
metodei sunt aceasi ca la ExportParameters.
 Cheile vor fi importate cu ImportParameters sau cu
FromXmlString
 Puteti exporta cheile de securitate si in CSP:
 Pas1> Creati un obiect CspParameters
 Pas2> Setati proprietatea
CspParameters.KeyContainerName
 Pas3> Creati un obiect RSACryptoServiceProvider folosind
un constructor care accepta obiectul CspParameters
 Pas4> Setati proprietatea PersistKeyInCsp true
 Veti folosii metodele Encrypt respectiv Decrypt.
 Cele 2 metode au 2 parametrii
 byte[] rgb: Un array de bytes ce contine mesajul ce va
fi criptat respectiv decriptat.
 Bool fOAEP: pt setarea modului de padding
 Prin folosirea hash-urilot puteti verifica
integritatea datelor. Un hash este deci un
checksum unic pentru fiecare fisier sau bucata de
data pentru care este calculat.
 Spre deosebire de criptare din un hash nu se pot
extrage informatiile initiale care l-au generat.
 Un exemplu larg raspandit de folosire de hash-uri
este verificarea parolelor fara a le stoca efectiv.
 Exista si algoritmi KeyedHash care cripteaza hash-ul
cu o cheie de criptare ce trebuie sa fie stiut atat de
cel ce cripteaza cat si de cel ce decripteaza.
 Algoritmii KeyedHash din .NET sunt:
 HMACSHA1: Hash Based Message Authentication Code
folosind SHA1. Accepta chei de orice lungime si produce
mesaje de 20bytes.
 MACTripleDES: Message Authentication Code folosind
TripleDES. Accepta chei de 8,16,24 biti si produce secvente
de 8bytes.
 Pas1> Creati obiectul de algoritm hash
 Pas2> Stocati data ce urmeaza sa fie hash-uita in
un array de bytes.
 Pas3> Apelati metoda
AlgoritmHash.ComputeHash
 Pas4> Hash-ul va fi stoca in array-ul de bytes
AlgorithHash.Hash
 Pas1> Creati o cheie secreta ce va fi comuna la toti
cei care vor calcula sau verifica hash-ul.
 Pas2> Creati un algoritm de hash ce va folosii cheia
secreta.
 Pas3> Stocati data de hash-uit in un array de bytes.
 Pas4> Apelati metoda ComputeHash
 Pas5> Hash-ul va fi dispnibil in arrayul de bytes Hash
 Prin semnarea digitala a fisierelor puteti proba
autenticitatea fisierului, verificand ca cel care a scris
fisierul detine o anumita cheie publica.
 In .NET Framework vom folosii
DSACryptoServiceProvider si RSACryptoServiceProvider
pentru a crea si verifica semnaturi digitale.
 Fiecare implementaza 4 metode:
 SignHash
 SignData
 VerifyHash
 VerifyData
 Pentru a genera semnatura unui fisier urmati pasii:
 Creati un obiect algorim de semnare digitala
 Stocati data care va fi semnata in un array de bytes
 Apelati metoda SignData si stocati semnatura
 Exportati cheia publica.
 Pentru a verifica semnatura digitala a unui fisier:
 Creati un obiect algorim de semnare digitala
 Importati semnatura si cheia publica
 Stocati data care va fi verificata in un array de bytes
 Apelati metoda VerifyData

S-ar putea să vă placă și