710 likes | 854 Views
Fejlett Programoz ási Technikák 2. 15 / 8. Az előző előadás tartalma:. Java Applet Felépítése Tulajdonságai Paraméterátadás JDBC Típusai Kapcsolat típusok Statement objektumok RecordSet Tranzakciók. Források. http://www.javaworld.com/javaworld/jw-04-2000/jw-0428-security.html
E N D
Az előző előadás tartalma: • Java Applet • Felépítése • Tulajdonságai • Paraméterátadás • JDBC • Típusai • Kapcsolat típusok • Statement objektumok • RecordSet • Tranzakciók
Források • http://www.javaworld.com/javaworld/jw-04-2000/jw-0428-security.html • http://www.cacr.math.uwaterloo.ca/hac/ • http://java.sun.com/security/ • http://www.javaworld.com/javaworld/jw-09-2002/jw-0913-jaas.html • http://java.sun.com/sfaq/verifier.html • http://ei.cs.vt.edu/~wwwbtb/book/chap14/index.html • http://www.cab.u-szeged.hu/WWW/java/kiss/security.html#ch3.1 • http://www2.tw.ibm.com/developerWorks/tutorial/pdf/j-sec1-a4.pdf • http://www2.tw.ibm.com/developerWorks/tutorial/pdf/j-sec2-a4.pdf
A mai előadás tartalma: • Számítógépes biztonság • Jáva és a biztonság • Biztonsági architektúra • Titkosító architektúra • JCE • JAAS • JSSE • GSSE
Számítógépes biztonság • Mit jelent a számítógépes biztonság? • Korlátlan erőforrással bármely rendszer feltörhető. • Cél: Olyan rendszer kiépítése melynek feltörése sokkal nagyobb energia mint a benne fellelhető információ értéke • A bonyolult rendszer nem biztos, hogy biztonságosabb. • A biztonsági szempontok a rendszer tervezésének alapvető paraméterei közé tartoznak.
Támadás típusok • Kategóriák: • Titkosság elleni támadás • Integritás elleni támadás • Rendelkezésre állás elleni támadás • Gyakori támadás fajták: • Nyers erő (brute force) • Trójai (trojan horse) • Ember középen (man-in-the-middle)
Feltörhetőség • 1977: Diffie and Hellman, 20 milliógép, 10 óra alatt • 1987: Diffie and Hellman, 200,000 gép, 10 óra alatt • 1993: Diffie and Hellman, M. Wiener, kulcs kereső IC, 5760 IC, $10.50/IC, 1.5 nap alatt • 1997: DES challenges I, DESCHALL, 96 nap • 1998: DES challenges II-1, distributed.net, 41 nap • 1998: DES challenges II-2, Electronic Frontier Foundation, 56 nap • 1999: DES challenges III, distributed.net, 22 nap
Jáva támadások • Trükkös kód • Régi, hack-elt javac • Class fájlok átírása (CGI jogosultságok) • Programok válogatása • Kapcsolat eltérítése (spoofing) (aláírt applet) • JVM bug
Jáva és a biztonság/1 • Nyílt: • A fordító és a virtuális gép forrása is hozzáférhető, megvizsgálható • Jáva nyelv: • Nincsenek mutatók • Minden primitív típus adott méretű • Hozzáférési szintek • Final • Hibakezelés • Fordító: • Az utasítások sorrendje fordító független • Bájtkód • Erősen típusos, fordításkor szigorú ellenőrzés • Objektum típusátformázás ellenőrzött (casting) • Minden metódus, tagváltozó hivatkozás ellenőrzésre kerül (pl.: private) • Primitív adattípusok nem keverhetőek a referencia típusokkal (1.5 auto boxing)
Jáva és a biztonság/2 • Futtató környezet: • Osztály betöltő • Bájt kód ellenőrző • Verzió problémák, Bináris kompatibilitás • Gonosz másik oldal (trükkös fordító, …) • Biztonsági Menedzser: • Az erőforrások elérésének ellenőrzése • Kód alapú • Felhasználó alapú • Szemét gyűjtő • Keretrendszerek, API-k
Osztály betöltő • Típusai: • Ősi (primordial) • Java osztálybetöltő • Saját osztály betöltőt is írhatunk (pl.: címtárból történő betöltésre…) • Feladatai: • Az osztály fájlok megtalálása (megfelelő sorrendben, biztonsági okokból) • Böngésző értelmezi a html kódot • Indít egy JVM-et • A JVM meghívja az Applet osztály betöltőt • A betöltő megpróbálja a helyi lemezről betölteni (java., …) (ősi) • Végigkeresi a classpath-ot (URLClassLoader) • Megpróbálja letölteni a webszerverről (Bönégsző specifikus class loader, vagy URLClassLoader) • A biztonsági beállítások lekérdezése • Egy osztály objektum definiálása megfelelő jogosultságokkal • A névterek kezelése
Bájt kód ellenőrző • Class file verifier • Az alap Java osztályokat nem bántja (esetenként a helyi lemezen lévő fájlokat sem) • Problémák: • Illegális mutató (egy objektumot más objektumként használunk) • Illegális bájtkód utasítások • Illegális paraméterek kiszűrése • Verem túlcsordulás • Illegális cast • Láthatóság megsértése • A fentieket megoldhatná a JVM csak lassabb lenne a végrehajtás • Folyamat: • Osztályállomány szintaktikus ellenőrzése • Osztályállomány összefüggéseinek ellenőrzése • Az utasításfolyam ellenőrzése • Külső hivatkozások ellenőrzése
Példa Exception in thread "main" java.lang.VerifyError: (class: TestVerify, method: add signature: ()I) Accessing value from uninitialized register 1 import java.awt.*; import java.applet.*; public class TestVerify extends Applet { public static void main(String[] args) { System.out.println("3 + 4 = " + add()); } static int add() { int a,b,c; a = 3; b = 4; return (a+b); } public void paint(Graphics g) { g.drawString("3 + 4 = " + add(), 10, 20); } } Compiled from TestVerify.java public class TestVerify extends java.applet.Applet { public TestVerify(); static int add(); public static void main(java.lang.String[]); public void paint(java.awt.Graphics); } Method TestVerify() 0 aload_0 1 invokespecial #9 <Method java.applet.Applet()> 4 return Method int add() 0 iconst_3 1 istore_0 2 iconst_4 3 istore_1 4 iload_0 5 iload_1 6 iadd 7 ireturn
Osztályállomány szintaktikus ellenőrzése ClassFile { u4 magic; (0xCAFEBABE) u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count]; } • Aláírás ellenőrzés • A struktúrák hosszának ellenőrzése • Constant pool ellenőrzése
Osztályállomány összefüggéseinek ellenőrzése • Olyan ellenőrizések melyeket a kód értelmezése nélkül meg lehet tenni • Final • Superclass • Konstans Tároló
Az utasításfolyam ellenőrzése • Adatfolyam ellenőrzés minden metóduson, a program egy-egy pontban az elérési útvonaltól függetlenül: • A stack ugyanolyan méretű és ugyanazokat az objektumokat tartalmazza • A regiszterek csak akkor használtak, ha megfelelő típust tartalmaznak • A metódusok megfelelő paraméterekkel hívódnak meg • A mezők megfelelő típusú értékkel módosulnak • A kódot statikusan ellenőrzi (nem futtatja) • Eredménye: • Futásidejű viselkedés bizonyíthatóan biztonságos • Futásidejű viselkedés bizonyíthatóan nem biztonságos • Futásidejű viselkedés sem nem bizonyíthatóan biztonságos sem nem bizonyíthatóan nem biztonságos
Külső hivatkozások ellenőrzése • Az előző menetekben nem ellenőrizte a külső osztályok és azok mezőinek valódiságát • Futás közben ellenőrzi a fentieket amikor betöltődnek az osztályok
Biztonsági Menedzser • Futás idejű biztonsági ellenőrzés • Java2 előtt egy absztrakt osztály volt (főleg a böngészők implementálták) • Homokozó • java.lang.SecurityManager • Biztonsági rendszabály alapú (policy based) • Természetesen ez is bővíthető
Hely függő (homokozó modell) • Java 1.0 • Nagyon szigorú a távoli kódokkal • Nincs kivétel
Kód alapú (digitálisan aláírt) • Java 1.1 • A digitálisan aláírt kód alapján eldönthetjük, hogy milyen jogosult-sággal akarjuk futtatni • Probléma: Érdekes játék, háttérben a bankkártya adatokat
Finomhangolás • Java2 • Aláírás/URL alapú • Távoli és helyi kódra isvonatkozhat • Policy fájl • Adott jogosultság adottkódrésznek adott erő-forráshoz
Védelmi tartomány • Rendszer Tartomány • Alkalmazás tartományok • Principal • Policy fájl grant signedBy "sysadmin", codeBase "file:/home/sysadmin/*" { permission java.security.SecurityPermission "Security.insertProvider.*"; permission java.security.SecurityPermission "Security.removeProvider.*"; permission java.security.SecurityPermission "Security.setProperty.*"; };
Lexikális szűkítés • Csak az adott kódrésznek adunk jogosultságot • Minden érzékeny kód egy helyre gyűjthető • java.security.AccessControler.doPrivileged()
Futás idejű hozzáférés vezérlés • I/O, … • SecurityManager.checkPermission() • A szál jogosultságát ellenőrzi • A hívási veremben minden metódust ellenőriz (az általuk használt objektumokat) • A legkisebb közös jogosultság • Használata: • java -Djava.security.manager HelloWorld • java.lang.System
Eszközök • Jar • Jarsigner • Keytool • Keystore • policytool
Kód biztonság • Bájt kód • Sok információt tartalmaz • Könnyű visszafejteni • Eszköz: • Mocha, … • Algoritmus másolás • Érzékeny információ (passwd, …) • Biztonsági rendszer megismerése • …
Megoldás • Obfuscator • A változó, metódus neveket lecseréli a constant pool-ban • Védett nevek használata (if, for, …) • Hosing • Értelmetel kódokat szúr be (pl.: pop, push) • Nagyban rontja a JVM JIT hatékonyságát • Írjunk olyan kódot melynél nem baj ha más is elolvassa
J2SE 1.5 biztonsági eszközök • JCA/JCE • JSSE • Java CertPath • JAAS/JGSS
JCA/JCE JCA • Titkosító architektúra • Alap titkosítás • Export korlátozás mentes • Aláírások, kivonat, .. JCE • Titkosító architektúra bővítmény • Fejlett titkosítás • Export korlátozás • Titkosítók
Titkosító architektúra • Titkosító eljárások: • Szimmetrikus kulcsú titkosítás (bulk encripiton) • DES • DEA • RC4 • AES • Aszimmetrikus kulcsú titkosítás (public key encripition) • RSA • Kivonatolás • MD5
Kivonatolás • Kulcs nélkül • Algoritmusok: • MD2, MD5 (128 bit) • SHA-1 (160 bit) • SHA-256,SHA-382, SHA-512 • Használata: MessageDigest.getInstance("MD5") .update(plaintext) .digest() • Kulcs használatával (MAC) • Algoritmusok: • HMAC/SHA-1 • HMAC/MD5 • Használata: KeyGenerator.getInstance("HmacMD5") .generateKey() Mac.getInstance("HmacMD5") .init(MD5key) .update(plaintext) .doFinal()
Példa kivonatoló import java.security.*; import javax.crypto.*; public class MessageDigestExample { public static void main (String[] args) throws Exception { if (args.length !=1) { System.err.println("Usage: java MessageDigestExample text"); System.exit(1); } byte[] plainText = args[0].getBytes("UTF8"); MessageDigest messageDigest = MessageDigest.getInstance("MD5"); messageDigest.update( plainText); System.out.println( "\nDigest: " ); System.out.println( new String( messageDigest.digest(), "UTF8") ); } }
Példa MAC import java.security.*; import javax.crypto.*; public class MessageAuthenticationCodeExample { public static void main (String[] args) throws Exception { if (args.length !=1) { System.err.println("Usage: java MessageAuthenticationCodeExample text");System.exit(1);} byte[] plainText = args[0].getBytes("UTF8"); System.out.println( "\nStart generating key" ); KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5"); SecretKey MD5key = keyGen.generateKey(); System.out.println( "Finish generating key" ); Mac mac = Mac.getInstance("HmacMD5"); mac.init(MD5key); mac.update(plainText); System.out.println( "\n" + mac.getProvider().getInfo() ); System.out.println( "\nMAC: " ); System.out.println( new String( mac.doFinal(), "UTF8") );}}
Titkosítás • Típusai: • Adatkezelés • Blokk titkosító (block cipher) • 64 bit • Padding (No padding,PKCS5,OAEP, SSL3) • Bit titkosító (stream cipher) • Algoritmus: • Nyilvános kulcsú • Titkos kulcsú • Működési módok • ECB (Electronic Code Book) • CBC (Cipher Block Chaining) • CFB (Cipher Feedback Mode) • OFB (Output Feedback Mode) • PCBC (Propagating Cipher Block Chaining)
Szimmetrikus titkosítás • Algoritmusok: • DES (Data Encription Standard) – 54 bit • TriplDES – 112 bit • AES (Advanced Encription Standard) – 128,192,256 bit • RC2,RC4,RC5 • Blowfish – 32 - 448 bit • PBE (Password Based Encryption) • Használatuk: • KeyGenerator.getInstance("DES"), .init(56),.generateKey() • Cipher.getInstance("DES/ECB/PKCS5Padding") • .init(Cipher.ENCRYPT_MODE, key) • .doFinal(plainText) • .init(Cipher.DECRYPT_MODE, key): • .doFinal(cipherText)
import java.security.*; import javax.crypto.*; public class PrivateExample { public static void main (String[] args) throws Exception { if (args.length !=1) { System.err.println("Usage: java PrivateExample text"); System.exit(1);} byte[] plainText = args[0].getBytes("UTF8"); System.out.println( "\nStart generating DES key" ); KeyGenerator keyGen = KeyGenerator.getInstance("DES"); keyGen.init(56); Key key = keyGen.generateKey(); System.out.println( "Finish generating DES key" ); Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); System.out.println( "\n" + cipher.getProvider().getInfo() ); System.out.println( "\nStart encryption" ); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] cipherText = cipher.doFinal(plainText); System.out.println( "Finish encryption: " ); System.out.println( new String(cipherText, "UTF8") ); System.out.println( "\nStart decryption" ); cipher.init(Cipher.DECRYPT_MODE, key); byte[] newPlainText = cipher.doFinal(cipherText); System.out.println( "Finish decryption: " ); System.out.println( new String(newPlainText, "UTF8") ); } }
Aszimmetrikus titkosítás • Tipikus kulcs hosszúság 1024 bit • 100, 1000 –szer lassabb mint a szimmetrikus • Algoritmusok: • RSA • Diffie-Hellman (kulcs csere) • Használata: • KeyPairGenerator.getInstance("RSA") • .initialize(1024) • .generateKeyPair(): • Cipher.getInstance("RSA/ECB/PKCS1Padding") • .init(Cipher.ENCRYPT_MODE, key.getPublic()) • .doFinal(plainText) • .init(Cipher.DECRYPT_MODE, key.getPrivate()) • .doFinal(cipherText)
import java.security.*; import javax.crypto.*; public class PublicExample { public static void main (String[] args) throws Exception { if (args.length !=1) { System.err.println("Usage: java PublicExample text");System.exit(1);} byte[] plainText = args[0].getBytes("UTF8"); System.out.println( "\nStart generating RSA key" ); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024); KeyPair key = keyGen.generateKeyPair(); System.out.println( "Finish generating RSA key" ); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); System.out.println( "\n" + cipher.getProvider().getInfo() ); System.out.println( "\nStart encryption" ); cipher.init(Cipher.ENCRYPT_MODE, key.getPublic()); byte[] cipherText = cipher.doFinal(plainText); System.out.println( "Finish encryption: " ); System.out.println( new String(cipherText, "UTF8") ); System.out.println( "\nStart decryption" ); cipher.init(Cipher.DECRYPT_MODE, key.getPrivate()); byte[] newPlainText = cipher.doFinal(cipherText); System.out.println( "Finish decryption: " ); System.out.println( new String(newPlainText, "UTF8") );}}
Digitális aláírások • Tipikusan hash+asszimmetrikus titkosítás • Módszerek: • Barkácsolós • Egyszerű • Algoritmusok: • MD2/RSA • MD5/RSA • SHA1/DSA • SHA1/RSA • Használatuk: • KeyPairGenerator.getInstance("RSA") • .initialize(1024) • .generateKeyPair() • Cipher.getInstance("MD5WithRSA") • .initSign(key.getPrivate()) • .update(plainText) • .sign() • .initVerify(key.getPublic()) and .verify(signature):
Példa import java.security.*; import javax.crypto.*; public class DigitalSignature2Example { public static void main (String[] args) throws Exception { if (args.length !=1) {System.err.println("Usage: java DigitalSignature1Example text");System.exit(1);} byte[] plainText = args[0].getBytes("UTF8"); System.out.println( "\nStart generating RSA key" ); KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024); KeyPair key = keyGen.generateKeyPair(); System.out.println( "Finish generating RSA key" ); Signature sig = Signature.getInstance("MD5WithRSA"); sig.initSign(key.getPrivate()); sig.update(plainText); byte[] signature = sig.sign(); System.out.println( sig.getProvider().getInfo() ); System.out.println( "\nSignature:" ); System.out.println( new String(signature, "UTF8") ); System.out.println( "\nStart signature verification" ); sig.initVerify(key.getPublic()); sig.update(plainText); try {if (sig.verify(signature)) {System.out.println( "Signature verified" );} else System.out.println( "Signature failed" ); } catch (SignatureException se) { System.out.println( "Signature failed" ); }}}
Digitális igazolványok • Hitelesító Hatóság - certificate authority(CA) • Certificate Revocation Lists (CRL) • Típusok: • X.509 • Tárolás: • Keystore
Kulcstároló (Keystore) • java.secutity • keytool -> .keystore • A privát kulcsokat és a megfelelő bizonyítványokat tároljuk benne • Jelszóval van titkosítva (Java Key Store) • Minden kulcs külön jelszóval titkosítható • Hash-el van védve a változtatástól • Természetesen ez is bővíthető (pl.: adatbázist akarunk használni fájl helyett)
Használata C:\Documents and Settings\bilickiv.INFORM>keytool -genkey -v -alias Vili -keyalg RSA Enter keystore password: jelszó What is your first and last name? [Unknown]: Vilmos Bilicki What is the name of your organizational unit? [Unknown]: SZTE What is the name of your organization? [Unknown]: InfTSZCS What is the name of your City or Locality? [Unknown]: Szeged What is the name of your State or Province? [Unknown]: Csongrád What is the two-letter country code for this unit? [Unknown]: HU Is CN=Vilmos Bilicki, OU=SZTE, O=InfTSZCS, L=Szeged, ST=Csongrád, C=HU correct? [no]: yes Generating 1á024 bit RSA key pair and self-signed certificate (MD5WithRSA) for: CN=Vilmos Bilicki, OU=SZTE, O=InfTSZCS, L=Szeged, ST=Csongrád, C=HU Enter key password for <Vili> (RETURN if same as keystore password): jelszó [Saving C:\Documents and Settings\bilickiv.INFORM\.keystore]
cacerts • Rendszer szintű tároló • A megbízható CA bizonyítványok tárolója • keytool -list -keystore cacerts
Certification Path API import java.security.*; import java.security.cert.*; // CertificateFactory for X.509 CertificateFactory cf =CertificateFactory.getInstance("X.509"); // Obtain CertPathValidator CertPathValidator cpv =CertPathValidator.getInstance("PKIX"); // Set the Trust anchor TrustAnchor anchor = new TrustAnchor((X509Certificate)cf.getCertificate("ca"),null); PKIXParameters params = newPKIXParameters(Collections.singleton(anchor)); // Revocation as false params.setRevocationEnabled(false); // Validate PKIXCertPathValidatorResult result =(PKIXCertPathValidatorResult) cpv.validate(cp, params);
JSE • Java Platform Security Extension (JSE) • Java Secure Socket Extension (JSSE) • Java Authorization and Authentication Service API (JAAS) • Java Crypography Extenision (JCE)
Java Secure Socket Extension • Jáva SSL megvalósítás • Vég-vég biztonság import java.io.*; import java.net.*; import javax.net.ssl.*; SSLServerSocketFactory sslsrvfact =SSLServerSocketFactory.getDefault(); SSLServerSocket s =sslsrvfact.createServerSocket(port); s.accept(); import java.io.*; import java.net.*; import javax.net.ssl.*; SSLSocketFactory sslfact =SSLSocketFactory.getDefault(); SSLSocket s =sslfact.createSocket(host, port);
import java.io.*; import java.net.*; import javax.net.ssl.*; public class HTTPSServerExample { public static void main(String[] args) throws IOException { SSLServerSocketFactory sslsf =(SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); ServerSocket ss = sslsf.createServerSocket(8080); while (true) { try { Socket s = ss.accept(); System.out.println( "Client connection made" ); BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); System.out.println(in.readLine()); PrintWriter out = new PrintWriter( s.getOutputStream() ); out.println("<HTML><HEAD><TITLE>HTTPS Server Example</TITLE>" + "</HEAD><BODY><H1>Hello World!</H1></BODY></HTML>\n"); out.close(); s.close(); } catch (Exception e) { e.printStackTrace();}}}} java -Djavax.net.ssl.keyStore=sslKeyStore -Djavax.net.ssl.keyStorePassword=password HTTPSServerExample