Osnove Java zaštite

Java Top

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ

1. Pregled

U ovom uputstvu proći ćemo kroz osnove sigurnosti na Java platformi. Također ćemo se usredotočiti na ono što nam je dostupno za pisanje sigurnih aplikacija.

Sigurnost je golema tema koja obuhvaća mnoga područja. Neki od njih dio su samog jezika, poput modifikatora pristupa i učitavača klasa. Nadalje, drugi su dostupni kao usluge, koje uključuju šifriranje podataka, sigurnu komunikaciju, autentifikaciju i autorizaciju, na samo nekoliko imena.

Stoga nije praktično steći smislen uvid u sve ovo u ovom vodiču. Međutim, pokušat ćemo steći barem smislen rječnik.

2. Jezične značajke

Iznad svega, sigurnost u Javi započinje upravo na razini jezičnih značajki. To nam omogućuje pisanje sigurnog koda, kao i koristi od mnogih implicitnih sigurnosnih značajki:

  • Statično tipkanje podataka: Java je statički otkucan jezik, koji smanjuje mogućnosti izvođenja vremena otkrivanja pogrešaka povezanih s tipom
  • Modifikatori pristupa: Java nam omogućuje upotrebu različiti modifikatori pristupa poput javnog i privatnog za kontrolu pristupa poljima, metodama i klasama
  • Automatsko upravljanje memorijom: Java ima upravljanje memorijom na bazi prikupljanja smeća, što oslobađa programere od ručnog upravljanja
  • Provjera bajtkoda: Java je kompajlirani jezik, što znači da pretvara kôd u bajtkod koji je platformi-agnostički i runtime provjerava svaki bytecode koji učita za izvršenje

Ovo nije cjelovit popis sigurnosnih značajki koje Java nudi, ali dovoljno je dobar da nam pruži neko uvjerenje!

3. Arhitektura sigurnosti u Javi

Prije nego što započnemo s istraživanjem određenih područja, provedimo neko vrijeme razumijevajući suštinsku arhitekturu sigurnosti na Javi.

Temeljna načela sigurnosti u Javi pokreću interoperabilna i proširiva Pružatelj usluga implementacije. Posebna provedba Pružatelj usluga može implementirati neke ili sve sigurnosne usluge.

Na primjer, neke od tipičnih usluga a Pružatelj usluga mogu implementirati su:

  • Kriptografski algoritmi (kao što su DSA, RSA ili SHA-256)
  • Postrojenja za generiranje, pretvorbu i upravljanje ključevima (kao što su ključevi specifični za algoritam)

Java se isporučuje s mnogi ugrađeni pružatelji usluga. Također, aplikaciji je moguće konfigurirati više davatelja s redoslijedom prioriteta.

Slijedom toga, okvir davatelja usluga u Java traži određenu implementaciju usluge kod svih pružatelja usluga prema redoslijedu po želji postaviti na njih.

Štoviše, u ovoj je arhitekturi uvijek moguće implementirati prilagođene pružatelje s priključnim sigurnosnim funkcijama.

4. Kriptografija

Kriptografija je temelj sigurnosnih značajki općenito i na Javi. Ovo se odnosi na alati i tehnike za sigurnu komunikaciju u nazočnosti protivnika.

4.1. Java kriptografija

Java Cryptographic Architecture (JCA) pruža okvir za pristup i implementaciju kriptografskih funkcionalnosti u Javi, uključujući:

  • Digitalni potpisi
  • Sažetak poruka
  • Simetrične i asimetrične šifre
  • Kodovi za provjeru autentičnosti poruke
  • Generatori ključeva i tvornice ključeva

Što je najvažnije, Java koristi Pružatelj uslugaimplementacije kriptografskih funkcija na temelju.

Štoviše, Java uključuje ugrađene davatelje za najčešće korištene kriptografske algoritme poput RSA, DSA i AES, da nabrojimo samo neke. Možemo koristite ove algoritme za dodavanje sigurnosti podacima u mirovanju, u uporabi ili u pokretu.

4.2. Kriptografija u praksi

Vrlo čest slučaj upotrebe u aplikacijama je pohranjivanje korisničkih lozinki. To kasnije koristimo za provjeru autentičnosti. Očito je da pohrana lozinki u običnom tekstu ugrožava sigurnost.

Dakle, jedno rješenje je šifriranje lozinki na takav način da je postupak ponovljiv, ali samo jednosmjeran. Taj je postupak poznat kao kriptografska hash funkcija, a SHA1 je jedan od takvih popularnih algoritama.

Pa, pogledajmo kako to možemo učiniti na Javi:

MessageDigest md = MessageDigest.getInstance ("SHA-1"); bajt [] hashedPassword = md.digest ("lozinka" .getBytes ());

Ovdje, MessageDigest je kriptografska usluga koja nas zanima. Mi smo koristeći metodu getInstance() zatražiti ovu uslugu od bilo kojeg dostupnog pružatelja usluga zaštite.

5. Infrastruktura javnog ključa

Infrastruktura javnog ključa (PKI) odnosi se na postavka koja omogućuje sigurnu razmjenu podataka putem mreže pomoću šifriranja javnim ključem. Ova se postavka oslanja na povjerenje koje se gradi između strana uključenih u komunikaciju. To se povjerenje temelji na digitalnim potvrdama koje je izdalo neutralno i pouzdano tijelo poznato kao Tijelo za izdavanje certifikata (CA).

5.1. PKI podrška u Javi

Java platforma ima API-je koji olakšavaju stvaranje, pohranu i provjeru valjanosti digitalnih certifikata:

  • KeyStore: Java nudi KeyStore klasa za trajno pohranjivanje kriptografskih ključeva i pouzdanih certifikata. Ovdje, KeyStore može predstavljati datoteke pohrane ključeva i datoteke pohrane povjerenja. Te datoteke imaju sličan sadržaj, ali se različito koriste.
  • CertStore: Osim toga, Java ima i CertStore klase, koja predstavlja javno spremište potencijalno nepouzdanih certifikata i popisa opoziva. Moramo doći do certifikata i popisa opoziva za izgradnju putova certifikata među ostalim oblicima.

Java ima ugrađena trgovina povjerenja pod nazivom "cacerts" koji sadrži certifikate za dobro poznate CA.

5.2. Java alati za PKI

Java ima nekoliko vrlo korisnih alata za olakšavanje pouzdane komunikacije:

  • Postoji ugrađeni alat nazvan "keytool" za stvaranje i upravljanje pohranom ključeva i pohranom povjerenja
  • Postoji i drugi alat "jarsigner" koji možemo koristiti za potpisivanje i provjeru JAR datoteka

5.3. Rad sa certifikatima na Javi

Pogledajmo kako možemo raditi sa certifikatima na Javi kako bismo uspostavili sigurnu vezu pomoću SSL-a. Uzajamno ovjerena SSL veza zahtijeva dvije stvari:

  • Predočiti potvrdu - Moramo predstaviti valjanu potvrdu drugoj strani u komunikaciji. Za to moramo učitati datoteku spremišta ključeva, gdje moramo imati svoje javne ključeve:
KeyStore keyStore = KeyStore.getInstance (KeyStore.getDefaultType ()); char [] keyStorePassword = "changeit" .toCharArray (); pokušajte (InputStream keyStoreData = novi FileInputStream ("keystore.jks")) {keyStore.load (keyStoreData, keyStorePassword); }
  • Potvrda potvrde - Također moramo potvrditi potvrdu koju je u komunikaciji predstavila druga strana. Za to trebamo učitati trgovinu povjerenja, gdje smo prethodno trebali imati pouzdane certifikate drugih strana:
KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType ()); // Učitaj trgovinu povjerenja iz datotečnog sustava kao i prije

To rijetko moramo raditi programski i obično prosljeđujemo sistemske parametre Javi u vrijeme izvođenja:

-Djavax.net.ssl.trustStore = truststore.jks -Djavax.net.ssl.keyStore = keystore.jks

6. Autentifikacija

Autentifikacija je postupak provjere predstavljenog identiteta korisnika ili računalo na temelju dodatnih podataka poput lozinke, tokena ili raznih drugih vjerodajnica koje su danas dostupne.

6.1. Autentifikacija u Javi

Java API-ji koriste priključne module za prijavu kako bi pružili različite i često višestruke mehanizme provjere autentičnosti aplikacijama. LoginContext pruža ovu apstrakciju, koja se pak odnosi na konfiguraciju i učitava odgovarajuću LoginModule.

Iako više davatelja čini dostupnim svoje prijavne module, Java ima neke zadane za upotrebu:

  • Krb5LoginModule, za autentifikaciju na temelju Kerberos-a
  • JndiLoginModule, za autentifikaciju na bazi korisničkog imena i lozinke potpomognute LDAP pohranom
  • KeyStoreLoginModule, za autentifikaciju zasnovanu na kriptografskom ključu

6.2. Prijava putem primjera

Jedan od najčešćih mehanizama provjere autentičnosti su korisničko ime i lozinka. Pogledajmo kako to možemo postići JndiLoginModule.

Ovaj je modul odgovoran za dobivanje korisničkog imena i lozinke od korisnika i njihovo provjeravanje u odnosu na uslugu direktorija konfiguriranu u JNDI:

LoginContext loginContext = novi LoginContext ("Uzorak", novi SampleCallbackHandler ()); loginContext.login ();

Evo nas koristeći primjerak LoginContext za izvršenje prijave. LoginContext uzima ime unosa u konfiguraciji prijave - u ovom slučaju to je „Uzorak“. Također, moramo pružiti primjerak CallbackHandler, koristiti LoginModule koja komunicira s korisnikom radi pojedinosti poput korisničkog imena i lozinke.

Pogledajmo našu konfiguraciju za prijavu:

Uzorak {com.sun.security.auth.module.JndiLoginModule potreban; };

Dovoljno jednostavno, sugerira da se koristimo JndiLoginModule kao obvezni LoginModule.

7. Sigurna komunikacija

Komunikacija putem mreže ranjiva je za mnoge vektore napada. Na primjer, netko može priskočiti u mrežu i čitati naše podatkovne pakete dok se prenose. Tijekom godina industrija je uspostavila mnoge protokole kako bi osigurala ovu komunikaciju.

7.1. Java podrška za sigurnu komunikaciju

Java nudi API-je za zaštitu mrežne komunikacije šifriranje, integritet poruke i provjera autentičnosti klijenta i poslužitelja:

  • SSL / TLS: SSL i njegov nasljednik, TLS, pružaju sigurnost nad nepouzdanom mrežnom komunikacijom putem šifriranja podataka i infrastrukture javnih ključeva. Java pruža podršku za SSL / TLS putem SSLSocket definirano u paketu “java.sigurnost.ssl“.
  • SASL: Jednostavni sloj provjere autentičnosti i sigurnosti (SASL) standard je za provjeru autentičnosti između klijenta i poslužitelja. Java podržava SASL kao dio paketa “java.sigurnost.sal“.
  • GGS-API / Kerberos: API generičke sigurnosne usluge (GSS-API) nudi ujednačen pristup sigurnosnim uslugama preko različitih sigurnosnih mehanizama poput Kerberosa v5. Java podržava GSS-API kao dio paketa “java.security.jgss“.

7.2. SSL komunikacija na djelu

Pogledajmo sada kako možemo otvoriti sigurnu vezu s drugim stranama u Javi pomoću SSLSocket:

SocketFactory tvornica = SSLSocketFactory.getDefault (); probajte (Socket connection = factory.createSocket (host, port)) {BufferedReader input = novi BufferedReader (novi InputStreamReader (connection.getInputStream ())); vrati input.readLine (); }

Evo, koristimo SSLSocketFactory stvoriti SSLSocket. Kao dio toga možemo postaviti neobavezne parametre poput paketa šifri i koji protokol koristiti.

Da bi ovo ispravno funkcioniralo, zacijelo smo stvorili i postavili našu trgovinu ključeva i trgovinu povjerenja kao što smo vidjeli ranije.

8. Kontrola pristupa

Kontrola pristupa odnosi se na štiteći osjetljive resurse poput datotečnog sustava ili baza podataka iz neopravdanog pristupa. To se obično postiže ograničavanjem pristupa takvim resursima.

8.1. Kontrola pristupa u Javi

Kontrolu pristupa možemo postići na Javi koristeći nastavu Politika i Dopuštenje posredovano kroz SecurityManager razred. SecurityManager je diojava.lang”I odgovoran je za provođenje provjera kontrole pristupa u Javi.

Kada učitavač klase učita klasu u vrijeme izvođenja, automatski dodjeljuje neka zadana dopuštenja klasi koja je inkapsulirana u Dopuštenje objekt. Osim ovih zadanih dozvola, klasi možemo dati više utjecaja putem sigurnosnih pravila. Njih predstavlja razred Politika.

Tijekom niza izvršavanja koda, ako vrijeme izvođenja naiđe na zahtjev za zaštićenim resursom, SecurityManager provjerava traženo Dopuštenje protiv instaliranog Politika kroz niz poziva. Slijedom toga, ili daje dozvolu ili baca SecurityException.

8.2. Java alati za politiku

Java ima zadanu implementaciju Politika koji čita podatke o autorizaciji iz datoteke svojstava. Međutim, unosi pravila u tim datotekama pravila moraju biti u određenom formatu.

Java se isporučuje s "policytool", grafičkim programom za sastavljanje datoteka politika.

8.3. Primjer kontrole pristupa

Pogledajmo kako možemo ograničiti pristup resursu poput datoteke na Javi:

SecurityManager securityManager = System.getSecurityManager (); if (securityManager! = null) {securityManager.checkPermission (novi FilePermission ("/ var / logs", "read")); }

Evo, koristimo SecurityManager da potvrdimo naš zahtjev za čitanje datoteke umotane u FilePermission.

Ali, SecurityManager delegira ovaj zahtjev AccessController. AccessController interno koristi instalirano Politika kako bi se došlo do odluke.

Pogledajmo primjer datoteke s pravilima:

grant {dozvola java.security.FilePermission <>, "read"; };

U osnovi dajemo dozvolu za čitanje svim datotekama svima. Ali, možemo pružiti puno precizniju kontrolu kroz sigurnosne politike.

Vrijedno je napomenuti da a SecurityManager možda se neće instalirati prema zadanim postavkama na Javi. To možemo osigurati uvijek pokrećući Java s parametrom:

-Djava.security.manager -Djava.security.policy = / put / do / sample.policy

9. XML potpis

XML potpisi su korisno u osiguranju podataka i osiguravanju integriteta podataka. W3C daje preporuke za upravljanje XML potpisom. XML potpis možemo koristiti za zaštitu podataka bilo koje vrste, poput binarnih podataka.

9.1. XML potpis u Javi

Java API podržava generiranje i provjeru valjanosti XML potpisa prema preporučenim smjernicama. Java XML API za digitalni potpis ugrađen je u paket “java.xml.crypto“.

Sam potpis samo je XML dokument. XML potpisi mogu biti tri vrste:

  • Odvojeno: Ova vrsta potpisa prelazi preko podataka koji su izvan elementa Signature
  • Omotavanje: Ova vrsta potpisa prelazi preko podataka koji su unutarnji u elementu Potpis
  • Omotano: Ova vrsta potpisa prelazi preko podataka koji sadrže sam element Signature

Svakako, Java podržava stvaranje i provjeru svih gore navedenih vrsta XML potpisa.

9.2. Stvaranje XML potpisa

Sada ćemo zasukati rukave i generirati XML potpis za naše podatke. Na primjer, možda ćemo uskoro poslati XML dokument mrežom. Stoga, željeli bismo da naš primatelj može potvrditi svoj integritet.

Pa, pogledajmo kako to možemo postići na Javi:

XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance ("DOM"); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance (); documentBuilderFactory.setNamespaceAware (istina); Dokument dokumenta = documentBuilderFactory .newDocumentBuilder (). Parse (novi FileInputStream ("data.xml")); DOMSignContext domSignContext = novi DOMSignContext (keyEntry.getPrivateKey (), document.getDocumentElement ()); XMLSignature xmlSignature = xmlSignatureFactory.newXMLSignature (signedInfo, keyInfo); xmlSignature.sign (domSignContext);

Da bismo pojasnili, generiramo XML potpis za naše podatke prisutne u datoteci “Data.xml”. U međuvremenu, treba napomenuti nekoliko stvari o ovom dijelu koda:

  • Prvo, XMLSignatureFactory je tvornička klasa za generiranje XML potpisa
  • XMLSigntaure zahtijeva a SignedInfo objekt preko kojeg izračunava potpis
  • XMLSigntaure također treba KeyInfo, koji obuhvaća ključ za potpis i certifikat
  • Konačno, XMLSignature potpisuje dokument pomoću privatnog ključa enkapsuliranog kao DOMSignContext

Kao rezultat, XML dokument sad će sadržavati element Signature, koji se može koristiti za provjeru njegove cjelovitosti.

10. Sigurnost izvan jezgre Java

Kao što smo do sada vidjeli, Java platforma pruža puno potrebnih funkcionalnosti za pisanje sigurnih aplikacija. Međutim, ponekad su to prilično niske razine i nisu izravno primjenjive na, primjerice, standardni sigurnosni mehanizam na webu.

Na primjer, kada radite na našem sustavu, općenito ne želimo čitati cjeloviti OAuth RFC i to sami primijeniti. Često su nam potrebni brži načini više razine za postizanje sigurnosti. Tu se pojavljuju aplikacijski okviri - oni nam pomažu u postizanju cilja s mnogo manje koda.

I, na platformi Java - to općenito znači Spring Security. Okvir je dio ekosustava Proljeće, ali se zapravo može koristiti izvan primjene čistog proljeća.

Jednostavno rečeno, pomaže postići provjeru autentičnosti, autorizaciju i druge sigurnosne značajke na jednostavan, deklarativni način na visokoj razini.

Naravno, Spring Security opsežno je obrađen u nizu vodiča, kao i na vođeni način, u tečaju Learn Spring Security.

11. Zaključak

Ukratko, u ovom smo tutorijalu prošli kroz visoku razinu sigurnosne arhitekture u Javi. Također smo razumjeli kako nam Java pruža implementacije nekih od standardnih kriptografskih usluga.

Također smo vidjeli neke uobičajene obrasce koje možemo primijeniti za postizanje proširive i priključive sigurnosti u područjima poput provjere autentičnosti i kontrole pristupa.

Da rezimiramo, ovo nam samo pruža kratak zavir u sigurnosne značajke Jave. Slijedom toga, svako od područja raspravljenih u ovom vodiču zaslužuje daljnje istraživanje. Ali nadamo se, trebali bismo imati dovoljno uvida da započnemo u ovom smjeru!

Dno Java

Upravo sam najavio novo Uči proljeće tečaj, usredotočen na osnove Spring 5 i Spring Boot 2:

>> PROVJERITE TEČAJ