Grunnleggende om Java-sikkerhet

Java Top

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

1. Oversikt

I denne opplæringen vil vi gå gjennom det grunnleggende om sikkerhet på Java-plattformen. Vi vil også fokusere på hva som er tilgjengelig for oss for å skrive sikre applikasjoner.

Sikkerhet er et enormt tema som omfatter mange områder. Noen av disse er en del av språket i seg selv, som tilgangsmodifikatorer og klasselastere. Videre er andre tilgjengelige som tjenester, som inkluderer datakryptering, sikker kommunikasjon, autentisering og autorisasjon, for å nevne noen få.

Derfor er det ikke praktisk å få meningsfull innsikt i alle disse i denne opplæringen. Imidlertid vil vi prøve å få i det minste et meningsfullt ordforråd.

2. Språkfunksjoner

Fremfor alt sikkerhet i Java begynner rett på nivå med språkfunksjoner. Dette lar oss skrive sikker kode, samt dra nytte av mange implisitte sikkerhetsfunksjoner:

  • Statisk datatyping: Java er et statisk skrevet språk som reduserer mulighetene for gjenkjenning av typelignende feil
  • Tilgangsmodifikatorer: Java tillater oss å bruke forskjellige tilgangsmodifikatorer som offentlig og privat for å kontrollere tilgang til felt, metoder og klasser
  • Automatisk minnehåndtering: Java har søppeloppsamlingsbasert minnestyring, som frigjør utviklere fra å administrere dette manuelt
  • Bytecode Verification: Java er et kompilert språk, som betyr at det konverterer kode til plattform-agnostisk bytecode, og runtime verifiserer hver bytekode den lastes inn for utføring

Dette er ikke en komplett liste over sikkerhetsfunksjoner som Java tilbyr, men det er bra nok til å gi oss litt sikkerhet!

3. Sikkerhetsarkitektur i Java

Før vi begynner å utforske spesifikke områder, la oss bruke litt tid på å forstå kjernearkitekturen til sikkerhet i Java.

Kjerneprinsippene for sikkerhet i Java er drevet av interoperabel og utvidbar Forsørger implementeringer. En bestemt implementering av Forsørger kan implementere noen eller alle sikkerhetstjenestene.

For eksempel er noen av de typiske tjenestene a Forsørger kan implementere er:

  • Kryptografiske algoritmer (som DSA, RSA eller SHA-256)
  • Nøkkelgenerering, konvertering og administrasjonsfasiliteter (for eksempel for algoritmespesifikke nøkler)

Java leveres med mange innebygde leverandører. Det er også mulig for et program å konfigurere flere leverandører med en rekkefølge.

Følgelig leverandørens rammeverk i Java søker etter en spesifikk implementering av en tjeneste i alle leverandører i den rekkefølgen de foretrekker sett på dem.

Dessuten er det alltid mulig å implementere tilpassede leverandører med pluggbare sikkerhetsfunksjoner i denne arkitekturen.

4. Kryptografi

Kryptografi er hjørnesteinen i sikkerhetsfunksjoner generelt og i Java. Dette refererer til verktøy og teknikker for sikker kommunikasjon i nærvær av motstandere.

4.1. Java-kryptografi

Java Cryptographic Architecture (JCA) gir et rammeverk for tilgang til og implementering av kryptografiske funksjoner i Java, inkludert:

  • Digitale signaturer
  • Meldingen fordøyes
  • Symmetriske og asymmetriske siffer
  • Autentiseringskoder for meldinger
  • Nøkkelgeneratorer og nøkkelfabrikker

Viktigst, Java bruker Forsørger-baserte implementeringer for kryptografiske funksjoner.

Videre inkluderer Java innebygde leverandører for ofte brukte kryptografiske algoritmer som RSA, DSA og AES, for å nevne noen. Vi kan bruk disse algoritmene for å gi sikkerhet til data i hvile, i bruk eller i bevegelse.

4.2. Kryptografi i praksis

En veldig vanlig brukssak i applikasjoner er å lagre brukerpassord. Vi bruker dette til autentisering på et senere tidspunkt. Nå er det åpenbart at lagring av ren tekstpassord kompromitterer sikkerheten.

Så en løsning er å kryptere passordene på en slik måte at prosessen er repeterbar, men likevel bare enveis. Denne prosessen er kjent som den kryptografiske hashfunksjonen, og SHA1 er en så populær algoritme.

Så la oss se hvordan vi kan gjøre dette på Java:

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

Her, MessageDigest er en kryptografisk tjeneste som vi er interessert i. Vi er ved hjelp av metoden getInstance() for å be om denne tjenesten fra noen av de tilgjengelige sikkerhetsleverandørene.

5. Offentlig nøkkelinfrastruktur

Public Key Infrastructure (PKI) refererer til oppsett som muliggjør sikker utveksling av informasjon over nettverket ved hjelp av kryptering med offentlig nøkkel. Dette oppsettet er avhengig av tillit som er bygget mellom partene som er involvert i kommunikasjonen. Denne tilliten er basert på digitale sertifikater utstedt av en nøytral og klarert myndighet kjent som en Certificate Authority (CA).

5.1. PKI-støtte i Java

Java-plattformen har API-er for å lette opprettelse, lagring og validering av digitale sertifikater:

  • KeyStore: Java gir KeyStore klasse for vedvarende lagring av kryptografiske nøkler og pålitelige sertifikater. Her, KeyStore kan representere både nøkkellagrings- og tillitsbutikkfiler. Disse filene har lignende innhold, men varierer i bruken.
  • CertStore: I tillegg har Java CertStore klasse, som representerer et offentlig lager med potensielt ikke-klarerte sertifikater og tilbakekallingslister. Vi må hente sertifikater og tilbakekallingslister for å bygge sertifikatsti blant andre bruksområder.

Java har en innebygd tillitsbutikk kalt “cacerts” som inneholder sertifikater for kjente CAer.

5.2. Java-verktøy for PKI

Java har noen veldig nyttige verktøy for å lette pålitelig kommunikasjon:

  • Det er et innebygd verktøy kalt “keytool” for å opprette og administrere nøkkelbutikk og tillitsbutikk
  • Det er også et annet verktøy “jarsigner” som vi kan bruke til å signere og verifisere JAR-filer

5.3. Arbeider med sertifikater i Java

La oss se hvordan vi kan jobbe med sertifikater i Java for å etablere en sikker forbindelse med SSL. En gjensidig godkjent SSL-tilkobling krever at vi gjør to ting:

  • Nåværende sertifikat - Vi må presentere et gyldig sertifikat til en annen part i kommunikasjonen. For det må vi laste nøkkellagerfilen, der vi må ha våre offentlige nøkler:
KeyStore keyStore = KeyStore.getInstance (KeyStore.getDefaultType ()); char [] keyStorePassword = "changeit" .toCharArray (); prøv (InputStream keyStoreData = ny FileInputStream ("keystore.jks")) {keyStore.load (keyStoreData, keyStorePassword); }
  • Bekreft sertifikat - Vi må også bekrefte sertifikatet presentert av en annen part i kommunikasjonen. For dette må vi laste tillitsbutikken, der vi må ha tidligere klarerte sertifikater fra andre parter:
KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType ()); // Last tillitsbutikken fra filsystemet som før

Vi trenger sjelden å gjøre dette programmatisk og normalt sende systemparametere til Java ved kjøretid:

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

6. Autentisering

Autentisering er prosess for å verifisere den presenterte identiteten til en bruker eller maskin basert på tilleggsdata som passord, token eller en rekke andre referanser som er tilgjengelige i dag.

6.1. Autentisering i Java

Java API-er bruker pluggbare påloggingsmoduler for å gi forskjellige og ofte flere autentiseringsmekanismer til applikasjoner. InnloggingContext gir denne abstraksjonen, som igjen refererer til konfigurasjon og laster en passende LoginModule.

Mens flere leverandører stiller inn påloggingsmodulene sine til rådighet, Java har noen tilgjengelige standarder for bruk:

  • Krb5LoginModule, for Kerberos-basert autentisering
  • JndiLoginModule, for brukernavn og passordbasert autentisering støttet av en LDAP-butikk
  • KeyStoreLoginModule, for kryptografisk nøkkelbasert autentisering

6.2. Logg inn med eksempel

En av de vanligste autentiseringsmekanismene er brukernavnet og passordet. La oss se hvordan vi kan oppnå dette gjennom JndiLoginModule.

Denne modulen er ansvarlig for å få brukernavnet og passordet fra en bruker og verifisere det mot en katalogtjeneste konfigurert i JNDI:

LoginContext loginContext = ny LoginContext ("Sample", ny SampleCallbackHandler ()); loginContext.login ();

Her er vi bruker en forekomst av InnloggingContext for å utføre påloggingen. InnloggingContext tar navnet på en oppføring i innloggingskonfigurasjonen - i dette tilfellet er det "Eksempel". Vi må også gi en forekomst av CallbackHandler, bruker LoginModule som samhandler med brukeren for detaljer som brukernavn og passord.

La oss ta en titt på innloggingskonfigurasjonen vår:

Eksempel på {com.sun.security.auth.module.JndiLoginModule kreves; };

Enkelt nok, antyder det at vi bruker JndiLoginModule som obligatorisk LoginModule.

7. Sikker kommunikasjon

Kommunikasjon over nettverket er sårbar for mange angrepsvektorer. For eksempel kan noen ta kontakt med nettverket og lese datapakkene våre når de overføres. Gjennom årene har bransjen etablert mange protokoller for å sikre denne kommunikasjonen.

7.1. Java-støtte for sikker kommunikasjon

Java tilbyr APIer for å sikre nettverkskommunikasjon med kryptering, meldingsintegritet og både klient- og serverautentisering:

  • SSL / TLS: SSL og dens etterfølger, TLS, gir sikkerhet over ikke-klarert nettverkskommunikasjon gjennom datakryptering og offentlig nøkkelinfrastruktur. Java gir støtte for SSL / TLS gjennom SSLSocket definert i pakken “java.security.ssl“.
  • SASL: Simple Authentication and Security Layer (SASL) er en standard for autentisering mellom klient og server. Java støtter SASL som en del av pakken “java.security.sasl“.
  • GGS-API / Kerberos: Generic Security Service API (GSS-API) gir jevn tilgang til sikkerhetstjenester over en rekke sikkerhetsmekanismer som Kerberos v5. Java støtter GSS-API som en del av pakken “java.security.jgss“.

7.2. SSL-kommunikasjon i aksjon

La oss nå se hvordan vi kan åpne en sikker forbindelse med andre parter i Java ved hjelp av SSLSocket:

SocketFactory fabrikk = SSLSocketFactory.getDefault (); prøv (Socket connection = factory.createSocket (host, port)) {BufferedReader input = new BufferedReader (new InputStreamReader (connection.getInputStream ())); return input.readLine (); }

Her bruker vi SSLSocketFactory å lage SSLSocket. Som en del av dette kan vi angi valgfrie parametere som krypteringssuiter og hvilken protokoll vi skal bruke.

For at dette skal fungere skikkelig, vi må ha opprettet og satt vår nøkkelbutikk og tillitsbutikk som vi så tidligere.

8. Tilgangskontroll

Tilgangskontroll refererer til beskytte sensitive ressurser som et filsystem eller kodebase fra uberettiget tilgang. Dette oppnås vanligvis ved å begrense tilgangen til slike ressurser.

8.1. Tilgangskontroll i Java

Vi kan oppnå tilgangskontroll i Java ved hjelp av klasser Politikk og Tillatelse formidlet gjennom Sikkerhetssjef klasse. Sikkerhetssjef er en del av “java.lang”-Pakken og er ansvarlig for å håndheve tilgangskontrollsjekker i Java.

Når klasselaster laster inn en klasse i løpetiden, gir den automatisk noen standardtillatelser til klassen som er innkapslet i Tillatelse gjenstand. Utover disse standardtillatelsene kan vi gi mer utnyttelse til en klasse gjennom sikkerhetspolicyer. Disse er representert av klassen Politikk.

Hvis kjøretiden møter en forespørsel om en beskyttet ressurs under sekvensen for kjøring av kode, Sikkerhetssjef bekrefter den forespurte Tillatelse mot installert Politikk gjennom samtalestakken. Derfor gir den enten tillatelse eller kaster SecurityException.

8.2. Java-verktøy for policy

Java har en standardimplementering av Politikk som leser autorisasjonsdata fra egenskapsfilen. Imidlertid må policyoppføringene i disse policyfilene være i et bestemt format.

Java leveres med "policytool", et grafisk verktøy for å komponere policyfiler.

8.3. Tilgangskontroll gjennom eksempel

La oss se hvordan vi kan begrense tilgangen til en ressurs som en fil i Java:

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

Her bruker vi Sikkerhetssjef for å validere vår leseforespørsel om en fil, pakket inn FilePermission.

Men, Sikkerhetssjef delegerer denne forespørselen til AccessController. AccessController internt bruker de installerte Politikk å komme til en avgjørelse.

La oss se et eksempel på policyfilen:

gi {tillatelse java.security.FilePermission <>, "les"; };

Vi gir i hovedsak lesetillatelse til alle filer for alle. Men, vi kan gi mye mer finkornet kontroll gjennom sikkerhetspolitikk.

Det er verdt å merke seg at en Sikkerhetssjef er kanskje ikke installert som standard i Java. Vi kan sikre dette ved å alltid starte Java med parameteren:

-Djava.security.manager -Djava.security.policy = / path / to / sample.policy

9. XML-signatur

XML-signaturer er nyttig for å sikre data og gi dataintegritet. W3C gir anbefalinger for styring av XML-signatur. Vi kan bruke XML-signatur for å sikre data av hvilken som helst type, som binær data.

9.1. XML-signatur i Java

Java API støtter generering og validering av XML-signaturer i henhold til de anbefalte retningslinjene. Java XML Digital Signature API er innkapslet i pakken “java.xml.crypto“.

Signaturen i seg selv er bare et XML-dokument. XML-signaturer kan være av tre typer:

  • Frittliggende: Denne typen signatur er over dataene som er eksterne signaturelementet
  • Innhylling: Denne typen signatur er over dataene som er interne i Signatur-elementet
  • Innhyllet: Denne typen signatur er over dataene som inneholder selve signaturelementet

Gjerne støtter Java oppretting og verifisering av alle ovennevnte typer XML-signaturer.

9.2. Opprette en XML-signatur

Nå bretter vi opp ermene og genererer en XML-signatur for dataene våre. For eksempel kan vi være i ferd med å sende et XML-dokument over nettverket. Derfor, vi ønsker at mottakeren skal kunne bekrefte integriteten.

Så la oss se hvordan vi kan oppnå dette i Java:

XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance ("DOM"); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance (); documentBuilderFactory.setNamespaceAware (true); Document document = documentBuilderFactory .newDocumentBuilder (). Parse (ny FileInputStream ("data.xml")); DOMSignContext domSignContext = ny DOMSignContext (keyEntry.getPrivateKey (), document.getDocumentElement ()); XMLSignature xmlSignature = xmlSignatureFactory.newXMLSignature (signert Info, keyInfo); xmlSignature.sign (domSignContext);

For å avklare genererer vi en XML-signatur for dataene våre i filen “Data.xml”. I mellomtiden er det noen få ting å merke seg om dette kodestykket:

  • For det første, XMLSignatureFactory er fabrikklasse for generering av XML-signaturer
  • XMLSigntaure krever en SignedInfo objektet den beregner signaturen over
  • XMLSigntaure trenger også KeyInfo, som innkapsler signeringsnøkkelen og sertifikatet
  • Endelig, XMLSignatur signerer dokumentet ved hjelp av den private nøkkelen innkapslet som DOMSignContext

Som et resultat, XML-dokumentet vil nå inneholde Signatur-elementet, som kan brukes til å verifisere integriteten.

10. Sikkerhet utenfor Core Java

Som vi har sett nå, gir Java-plattformen mye nødvendig funksjonalitet for å skrive sikre applikasjoner. Noen ganger er disse imidlertid ganske lavt og gjelder ikke direkte for for eksempel standard sikkerhetsmekanisme på nettet.

For eksempel når du jobber med systemet vårt, Vi ønsker generelt ikke å måtte lese hele OAuth RFC og implementere det selv. Vi trenger ofte raskere måter på høyere nivå for å oppnå sikkerhet. Det er her applikasjonsrammer kommer inn i bildet - disse hjelper oss med å nå vårt mål med mye mindre kjelekode.

Og på Java-plattformen - generelt betyr det vårsikkerhet. Rammeverket er en del av vårens økosystem, men det kan faktisk brukes utenfor ren vårapplikasjon.

Enkelt sagt hjelper det å oppnå autentisering, autorisasjon og andre sikkerhetsfunksjoner på en enkel, erklærende, høyt nivå måte.

Selvfølgelig blir Spring Security omfattende dekket i en serie opplæringsprogrammer, så vel som på en guidet måte, i kurset Learn Spring Security.

11. Konklusjon

Kort sagt, i denne opplæringen gikk vi gjennom sikkerhetsarkitekturen på høyt nivå i Java. Vi forsto også hvordan Java gir oss implementeringer av noen av de standard kryptografiske tjenestene.

Vi så også noen av de vanlige mønstrene vi kan bruke for å oppnå utvidbar og pluggbar sikkerhet i områder som autentisering og tilgangskontroll.

For å oppsummere gir dette oss bare et innblikk i sikkerhetsfunksjonene til Java. Følgelig fortjener hvert av områdene som er diskutert i denne opplæringen ytterligere utforsking. Men forhåpentligvis skal vi ha nok innsikt til å komme i gang i denne retningen!

Java bunn

Jeg kunngjorde nettopp det nye Lær våren kurs, med fokus på det grunnleggende i vår 5 og vårstøvel 2:

>> KONTROLLER KURSET

$config[zx-auto] not found$config[zx-overlay] not found