760 likes | 952 Views
KATEDRA POČÍTAČOV A INFORMATIKY BEZPEČNOSŤ INFORMAČNÝCH SYSTÉMOV Security extensions in JAVA (JAAS, JCE, JSSE). Katar ína Dudášová 4. roč., 2003/04. Java Authentication & Authorization Service (JAAS). Motivácia.
E N D
KATEDRA POČÍTAČOV A INFORMATIKYBEZPEČNOSŤ INFORMAČNÝCH SYSTÉMOVSecurity extensions in JAVA(JAAS, JCE, JSSE) Katarína Dudášová 4. roč., 2003/04
Motivácia • JAAS rozširuje existujúcu bezpečnostnú architektúru (Java2 platform), ktorá je zameraná na kód – code-centric • Práva boli pridelené na základe kódu: • odkiaľ kód pochádza • či bol digitálne podpísaný a ak áno, tak kým • Použitím JAAS môže byť kontrola prístupu rozšírená – zaujíma nás nielen to, aký kód „beží“, ale aj kto ho spúšťa
Java Authentication & Authorization • Množina API, ktorá umoňuje službám autentifikáciu a riadenie prístupu používateľov • Implementuje java verziu štandardu PAM (Pluggable Authentication Module) a podporuje autorizáciu na základe používateľa (user-based authorization) Používa sa na: • autentifikáciu - spoľahlivé a bezpečné určenie, kto práve vykonáva java kód (bez ohľadu na to, či ide o aplikáciu, applet, servlet...) • autorizáciu – či používateľ má požadované práva (acces control rights/permissions) pre vykonanie príslušnej činnosti
Charakteristika • JAAS autentifikácia je vykonávana ako pripojiteľný modul • Toto dovoľuje aplikáciám zostať nezávislými od autentifikačnej technológie (nové alebo updatované technológie môžu byť pripojené bez potreby modifikácie samotnej aplikácie) • Poskytuje flexibilitu pri kontrole prístupu – autorizácia môže byť: • user-based • group-based • role-based
Základné triedy JAAS • Common Classes • Subject, Principal, Credential • Authentication Classes • LoginContext, LoginModule, CallbackHandler, Callback • Authorization Classes • Policy, AuthPermission, PrivateCredentialPermission
Common classes • sú využívané autentifikáciou aj autorizáciou • kľúčovou triedou je Subjekt – reprezentuje zoskupenie informácií pre entitu ako napr. osobu, ktorá spúšťa kód
Subjects and Principals • JAAS používa termín • Subject– na odkazovanie sa na akéhokoľvek používateľa výpočtových služieb (to znamená, že aj samotná výpočtová služba je subject) Na idetifikovanie subjektu, s ktorým prichádza služba do styku sa používa meno subjeku – to však môže byť pre jeden subjekt a inú službu rôzne, preto: • principal reprezentuje meno spojené so subjektom. Keďže subjekt môže mať niekoľko mien, subjekt zahŕňa množinu principals. Je to akási identifikácia subjektu, odlíšenie od ostatných subjektov
public interface Principal { public String getName(); } • public final class Subject { public Set getPrincipals() { } } • Principal sa môže pripojiť k subjektu po úspešnej autentifikácii k službe • Autentifikácia reprezentuje proces, v ktorom jeden subjekt overí identitu druhého bezpečným spôsobom (inak by mohol získať prístup do systému tak, že sa vydáva za niekoho iného) – informácia, ktorú môže vedieť (heslo) alebo mať (odtlačok prsta) len subjekt, prípadne ktorú môže produkovať len subjekt (podpísať data privátnym kľúčom)
Credentials (1) - security related attributes • Niektoré služby potrebujú pripojiť k menu ďalšie bezpečnostné atribúty, na ktoré sa JAAS odkazuje ako na credentials, ktoré môžu obsahovať info potrebné na autentifikáciu subjektu pre novú službu: • passwords • kerberos tickets • public key certificates • Môžu taktiež obsahovať dáta, ktoré subjektu umožňujú vykonávať určité aktivity (napr. kryptografický kľúč umožňuje subjektu podpísať alebo zašifrovať dáta)
Credentials (2) • JAAS neobsahuje žiadne knižičné triedy, ktoré reprezentujú credentials • môže ich reprezentovať akákoľvek trieda • ich existujúce implementácie (java.security.cert.Certificate) môžu byť ľahko pripojené k JAAS • takisto aj iné implementácie môžu byť zakomponované • implemetácia nemusí nevyhnutne obsahovať dáta, môže to byť odkaz na ne
JAAS rozdeľuje credentials do dvoch množín: • verejné (public) – na prístup nie sú potrebné žiadne práva, napr. • public key certificates • Kerberos tickets • súkromné (private) – prístup je bezpečnostne kontrolovaný, napr. • private keys • encryption keys • passwords, etc.
public final class Subject { ... public Set getPublicCredentials() { } // not security checked public Set getPrivateCredentials() { } // security checked }
Subjekt sa vytvára použitím týchto konštruktorov: • public Subject(); vytvorí subjekt s prázdnou množinou principals a credentials • public Subject(boolean readOnly, Set principals, Set pubCredentials, Set privCredentials); vytvorí subjekt s danými (špecifikovanými) množinami principals a credentials boolean argument zaručuje, že subjekt je len na čítanie (nezameniteľnosť)
Ak subjekt nebol vytvorený ako readonly, je tak možne učiniť volaním metódy public void setReadOnly() • ak je subjekt určený len na čítanie, pokus pridávať alebo meniť principals alebo credentials vyústi do IllegalStateException • public boolean isReadOnly()slúži na zistenie stavu • Na získanie množiny principals sú metódy: public SetgetPrincipals(); //all public Set getPrincipals(Class c); // len tie, ktoré sú inštanciou triedy c ak subjekt nemá asociované tieto množiny, vráti sa prázdna množina
Podobne na získanie množín obsahujúcich data týkajúce sa bezpečnosti slúžia metódy public Set getPublicCredentials(); public Set getPublicCredentials(Class c); // verejne dostupné public Set getPrivateCredentials(); public Set getPrivateCredentials(Class c); // dostupné len pre autentifikovaných
Trieda Subject obsahuje nasledovné metódy (zdedené od java.lang.Object) • public boolean equals(Object o); • public String toString(); • public int hashCode(); Na prácu s konkrétnym subjektom slúžia nasledovné metódy: static ObjectdoAs(Subject subject, PrivilegedAction action) static ObjectdoAsPrivileged(Subject subject, PrivilegedAction action, AccessControlContext acc)
Obidve metódy: • spoja subjekt s AccessControlContext-om aktuálneho vlákna • Vykonajú akciu – action • Action beží v podstate ako subjekt • Prvá metóda môže vyvolať výnimku (runtime exception), ale normálnym vykonaním vráti Object • Na volanie metód doAs sa vyžaduje AuthPermission("doAs")
Authentication Classes • Pre autentifikáciu subjektu sa vykonajú nasledovné kroky: • Aplikácia vytvorí LoginContext • LoginContext sa dotazuje na konfiguráciu Configuration (trieda javax.security.auth.login.Configuration) – obsahuje info o tom, ktoré login moduly (LoginModules) sa majú použiť pre konkrétnu aplikáciu a v akom poradí sa majú vykonať • Aplikácia vyvolá LoginContext metódu login
4. login metóda vyvolá príslušné login moduly. Každý z nich sa bude pokúšať autentifikovať Subject. V prípade úspechu login modul asociuje so subjektom príslušné principals a credentials 5. LoginContext vráti aplikácii výsledok autentifikácie (autentification status) 6. Ak bola autentifikácia úspešná, aplikácia získa od LoginContextu autentifikovaný Subject
Interface LoginModulejavax.security.auth.spi • popisuje rozhranie implementované poskytovateľmi autentifikačných technológií • LoginModules sú pripojené k aplikácii – poskytujú konkrétny typ autentifikácie • Configuration špecifikuje, ktorý modul (moduly) majú byť použité s danou aplikáciou – preto ich môže byť pripojených viac bez toho, aby bolo nutné modifikovať aplikáciu
Pluggable Authentication Module • S týmto modulom môže byť pridaných niekoľko autentifikačných technológií bez potreby meniť login službu (login service) • Môže byť použitý na integráciu rôznych login služieb – RSA, DCE, Kerberos, S/Key • Umožňuje vytvoriť heterogénne prostredie, v ktorom je umiestnených niekoľko bezpečnostných mechanizmov • PAM API – standard API for unified login
LoginContext class • reprezentuje implementáciu PAM v Jave public final class LoginContext { public LoginContext(String name) { } public void login() { } // two phase process public void logout() { } public Subject getSubject() { } // get the authenticated Subject } public interface LoginModule { boolean login(); // 1st authentication phase boolean commit(); // 2nd authentication phase boolean abort(); boolean logout(); }
JAAS zabezpečuje • úspešné vykonanie všetkých login modulov alebo ani jedného: • LoginContext vykonáva autentifikáciu v dvoch krokoch • login – pokus o autentifikáciu. Ak prebehne úspešne, prejde sa do druhej fázy: • commit – potvrdenie procesu autentifikácie, tu sa asociujú credentials a principals so subjektom • ak niektorá z týchto fáz neprebehne úspešne, potom sa spustí • abort – „vyčistí“ sa prostredie od začatých a nedokončených záležitostí
Autorizácia (authorization) • Po úspešnej autentifikácii JAAS ponúka možnosť kontroly prístupu nad množinou principals prislúchajúcich konkrétnemu subjektu – principal-based access controls (kontrola prístupu na základe toho, kto spúšťa kód) • JAAS sleduje nasledovný model: • existujú bezpečné zdroje (security resources) • sú definované požiadavky, na základe ktorých k nim môžu pristupovať príslušné (autorizované) pomenované subjekty (principals)
Policy • Abstraktná trieda, ktorá reprezentuje kontrolu prístupu (access control policy) • Defaultne JAAS poskytuje implementáciu kontroly prístupu založenú na súboroch (file-based) • Každá podtrieda musí implementovať nasledujúce metódy public abstract PermissionCollection getPermissions (Subject subject, CodeSource codesource); • vráti Permissions prislúchajúce subjektu a kódu • vyžadujeAuthPermssion("getPolicy") public abstract void refresh(); • updatuje runtime Policy modifikáciami, ktoré boli uskutočnené od vtedy, ako bol posledný čas načítaný • vyžaduje AuthPermission("refreshPolicy").
Práva pridelené bežiacemu kódu zistíme nasledovne: Policy policy = Policy.getPolicy(); PermissionCollection perms = policy.getPermissions(subject, codeSource); • Každý záznam v Policy je reprezentovaný ako grant: grant CodeBase ["URL"], Signedby ["signers"], Principal [Principal_Class]"Principal_Name" { Permission Permission_Class ["Target_Name"] [, "Permission_Actions"] [, signedBy "SignerName"]; }; • Význam • Práva (permissions) budú pridelené akémukoľvek kódu stiahnutom z CodeBase, ktorý je podpísaný signers, ak subjekt spúšťajúci kód má špecifikované Principals vo svojej množine principals
Príklad grant CodeBase "foo.com", Signedby "foo", Principal com.sun.security.auth.SolarisPrincipal "duke" { permission java.io.FilePermission "/home/duke", "read, write"; }; • Kód z "foo.com" podpísaný "foo" bude bežať ako SolarisPrincipal s menom "duke" s povolením čítať/zapisovať v "/home/duke" • bežať ako Principal znamená, že bude vyvolaná metóda Subject.doAs()
AuthPermission • Táto trieda zahŕňa základné prístupové práva pre JAAS • Objekt tejto triedy priradzuje práva pristupovať k objektom tried • Policy • Subject • LoginContext • Configuration • Obsahuje meno – "target name", ktoré reprezentuje prístupové právo • Konštruktor • public AuthPermission(String name);
Skupiny (groups) a role (roles) // an administrator role can access user passwords grant Principal foo.Role "administrator" { permission java.io.FilePermission "/passwords/-", "read, write"; } // a basketball team (group) can read its directory grant Principal foo.Team "SlamDunk" { permission java.io.FilePermission "/teams/SlamDunk/-", "read"; }
Požiadavky • JAAS 1.0 požaduje mať nainštalované • JavaTM 2 SDK, Standard Edition, v 1.3alebo • JavaTM 2 Runtime Environment v 1.3
JCA princípy • Nezávislosť implementácie • implementácia služby sa získa od poskytovateľa (služba môže mať viacero implementácií, ktoré poskytujú rôzni provideri) rovnakým spôsobom • Interoperabilita • rôzne implementácie navzájom spolupracujú – používajú kľúče, overujú podpisy • Nezávislosť algoritmov • dosahuje sa definovaním cryptographic engines (služieb) a definovaním tried, ktoré ich implementujú – engine classes (napr. MessageDigest, Signature, KeyFactory, KeyPairGenerator) • Rozšíriteľnosť algoritmov • Nový algoritmus, ktorý spadá do niektorého enginu, môže byť ľahko pridaný
Architektúra • Cryptographic Service Providers • balík (množina balíkov), ktoré poskytujú konkrétnu implementáciu niektorej časti Security API • program môže požiadať o objekt pre nejakú službu a získa tak implementáciu od jedného z nainštalovaných providerov (poskytovateľov) • Runtime môže byť nainštalovaný s rozličnými providermi, ktorí majú nastavenú prioriu (poradie, v ktorom majú byť prehľadávaní pre danú službu, ak nie je zadaný jeden konkrétny) • Key Management • Databáza nazývaná keystore sa používa na skladovanie kľúčov a certifikátov • Keystore je prístupný aplikáciám pre účely autentifikácie, podpisovania prostredníctvom triedy KeyStore
Koncept • engine class popisuje šifrovaciu službu abstraktne – bez konkrétnej implementácie • šifrovacia služba je spojená s • nejakým algoritmom • operáciou • generovania al. poskytovania šifrovacieho materiálu (kľúče, parametre) • generovania objektov (keystores, certificates)
V Java 2 SDK sú definované nasledujúce engine classes: • MessageDigest • vypočíta message digest (hash) zo špecifikovaných dát static MessageDigest getInstance(String algorithm) MessageDigest.getInstance("SHA-1") • Signature • Napodpisovanie dát a overovanie digitálnych podpisov • KeyPairGenerator • Slúži na vygenerovania páru súkromný – verejný kľúč vhodný pre daný šifrovací algoritmus • KeyFactory • Slúži na konverziu šifrovacieho kľúča na jeho špecifikáciu a naopak
CertificateFactory • Používa sa na vytváranie certifikátov pre verejné kľúče (public key certifikates) a Certificate Revocation Lists (CRLs) • KeyStore • Vytvorenie a správa keystoru • AlgorithmParameters • Slúži na správu parametrov konkrétneho algoritmu (týka sa kódovania aj dekódovania) • Prístup k parametrom nie je transparentný – je možné len získať algoritmus zviazaný s množinou parametrov alebo typ kódovania pre množinu parametrov (existuje aj transúarentná reprezentácia, kde je možné pristupovať k jednotlivým hodnotám parametrov) • AlgorithmParameterGenerator • Generuje parametre pre konkrétny algoritmus • SecureRandom • Generuje náhodné alebo pseudonáhodné čísla
Vo verzii 1.4 Java 2 SDK boli pridané nasledujúce enginy: • CertPathBuilder • Slúži na vytváranie cerifikačných ciest – certificate paths (tiež certificate chain) • CertPathValidator • Slúži pre potvrdenie platnosti certifikačných ciest static CertPathValidatorgetInstance(String alg) CertPathValidatorResultvalidate(CertPath certPath, CertPathParameters params) • CertStore • Používa sa získanie certifikátov (Certificates) a CRLs zo skladu
Java Cryptography Extension (JCE) • Rozširuje JCA (Java Cryptography Architecture) • Pôvodne voliteľný balík – rozšírenie k Java 2 SDK • JCE 1.2.x • JCE 1.3.x • Teraz je súčasťou Java 2 SDK, v1.4 • Zahŕňa prostriedky pre vynútenie dodržania vymedzení týkajúcich sa kryptografických algoritmov a šifrovacej sily prípustnej v appletoch/aplikáciách v rôznych právnych systémoch • Kôli právnym obmedzeniam v niektorých krajinách je v Java 2 SDK, v1.4 použité šifrovanie s obmedzenou silou, je prístupná aj „unlimited stregth“ version
JCE je množina balíkov, ktorá poskytuje implementáciu pre: • šifrovanie – encryption • generovanie kľúčov – key generation • vybratie kľúča – key agreement • Message Authentication Code (MAC) algoritmy • JCE je navrhnuté tak, aby mohli byť pripojené ďalšie knižnice pre šifrovanie (ako service providers), taktiež nové algoritmy môžu byť pridané jednoducho
SunJCE podporuje nasledovné algoritmy: • DES • DESede • AES (with Java 2 SDK, v 1.4.2) • Blowfish • PBEWithMD5AndDES • PBEWithMD5AndTripleDES • Diffie-Hellman key agreement among multiple parties • HmacMD5 • HmacSHA1
Rozšírenie oproti JCA spočíva: • vo väčšom počte šifrovacích algoritmov • v možnosti šifrovania symetrickými kľúčmi • v pridaní implementácie KeyAgreement protokolu • v pridaní šifrovanej práce s prúdmi údajov • v možnosti šifrovať akýkoľvek objekt
Core classes • Cipher • CipherInputStream, CipherOutputStream • KeyGenerator • SecretKeyFactory • Používa sa na konvertovanie tajných kľúčov z transparentnej reprezentácie na netransparnetnú a naopak • SealedObject • KeyAgreement • Mac
Cipher • Tvorí jadro JCE • Poskytuje funkcionality pre šifrovanie a dešifrovanie • Inštanciu vytvoríme pomocou statickej metódy public static Cipher getInstance(String transformation); public static Cipher getInstance(String transformation, String provider); • transformation • opisuje operácie, ktoré sa vykonajú nad vstupom, aby sa vyprodukoval vystup • je to vždy meno šifrovacieho algoritmu (napr. DES)
Cipher objekt je potrebné inicializovať do jedného zo štyroch módov, ktoré sú definované ako celočíselné konštanty v tejto triede. Odkazuje sa na ne pomocou symbolických mien: ENCRYPT_MODE – šifrovanie dát DECRYPT_MODE – dešifrovanie dát WRAP_MODE – zaobalenie kľúča do bajtov, aby mohol byť bezpečne prenesený UNWRAP_MODE – opak – získa sa java.security.Key objekt • Na inicializáciu sa slúži metóda public void init(int opmode, Key key, AlgorithmParameters params, SecureRandom random) • môže mať rôzny počet parametrov, ak niektoré potrebné pre algoritmus nie sú uvedené, provider zabezpečí vlastné
Kódovanie a dekódovanie • môže prebiehať • v jednom kroku (single-part operation) • v niekoľkých krokoch (multi-part operation) • vhodné vtedy, ak nevieme, aké veľké budú data, alebo ak sú príliš veľké na to, aby boli naraz v pamäti • Pre jednokrokové šifrovanie/dešifrovanie public byte[] doFinal(byte[] input); • Pre viackrokové šifrovanie/dešifrovanie public byte[] update(byte[] input); a musí byť ukončené doFinal() metódou
Správa parametrov potrebných pre algoritmus • Parametre sa buď • explicitne určia v init() metóde v aplikácii • vygeneruje ich sama implementácia algoritmu • Parametre použité pri šifrovaní je možné získať pomocou Cipher objektu volaním metódy getParameters(), ktorá vráti objekt java.security.AlgorithmParameters alebo null, ak nie sú používané žiadne • tie isté parametre, ktoré boli použité pri šifrovaní, musia byť použité aj pri dešifrovaní (získajú sa a inicializuje sa nimi Cipher objekt pre dekódovanie)
import javax.crypto.*; import java.security.AlgorithmParameters; // získanie Cipher objektu pre password based encr. Cipher c = Cipher.getInstance("PBEWithMD5AndDES"); // inicializácia bez poskytnutia parametrov c.init(Cipher.ENCRYPT_MODE, myKey); // zašifrovanie dát byte[] cipherText = c.doFinal("This is just an example".getBytes()); // získanie použitých parametrov AlgorithmParameters algParams = c.getParameters(); // parametre sa zakódujú pre neskoršie použitie byte[] encodedAlgParams = algParams.getEncoded();
import javax.crypto.*; import java.security.AlgorithmParameters; // získanie objektu reprezentujúceho parametre // pre password based encoding AlgorithmParameters algParams; algParams = AlgorithmParameters.getInstance("PBEWithMD5AndDES"); // inicializuje sa parametrami použitými pri šifrovaní algParams.init(encodedAlgParams); // získa sa cipher objekt pre password-basedencryption Cipher c = Cipher.getInstance("PBEWithMD5AndDES"); // inicializuje sa pre dekódovanie pomocou init metódy // aj s parametrami c.init(Cipher.DECRYPT_MODE, myKey, algParams);