Documente Academic
Documente Profesional
Documente Cultură
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