En guide til Java GSS API

Java Top

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN

1. Oversigt

I denne vejledning forstår vi Generic Security Service API (GSS API), og hvordan vi kan implementere det i Java. Vi får se, hvordan vi kan sikre netværkskommunikation ved hjælp af GSS API i Java.

I processen opretter vi enkle klient- og serverkomponenter, der sikrer dem med GSS API.

2. Hvad er? GSS API?

Så hvad er egentlig Generic Security Service API? GSS API giver en generel ramme for applikationer til at bruge forskellige sikkerhedsmekanismer som Kerberos, NTLM og SPNEGO på en pluggbar måde. Derfor hjælper det applikationer med at afkoble sig direkte fra sikkerhedsmekanismerne.

For at afklare spænder sikkerheden her godkendelse, dataintegritet og fortrolighed.

2.1. Hvorfor har vi brug for det? GSS API?

Sikkerhedsmekanismer som Kerberos, NTLM og Digest-MD5 er ret forskellige i deres evner og implementeringer. Typisk finder en applikation, der understøtter en af ​​disse mekanismer, det ret skræmmende at skifte til en anden.

Det er her en generisk ramme som GSS API giver applikationer en abstraktion. Derfor kan applikationer, der bruger GSS API, forhandle om en passende sikkerhedsmekanisme og bruge den til kommunikation. Alt dette uden faktisk at skulle implementere mekanismespecifikke detaljer.

2.2. Hvordan gør GSS API arbejde?

GSS API er en tokenbaseret mekanisme. Det fungerer efter udveksling af sikkerhedstokener mellem jævnaldrende. Denne udveksling sker typisk over et netværk, men GSS API er agnostisk for disse detaljer.

Disse tokens genereres og behandles af de specifikke implementeringer af GSS API. Det syntaks og semantik for disse tokens er specifikke for sikkerhedsmekanismen forhandlet mellem jævnaldrende:

Det centrale tema i GSS API drejer sig om en sikkerhedskontekst. Vi kan etablere denne sammenhæng mellem jævnaldrende gennem udveksling af tokens. Vi kan have brug for flere udvekslinger af tokens mellem jævnaldrende at etablere konteksten.

Når vi er etableret i begge ender, kan vi bruge sikkerhedskonteksten til at udveksle data sikkert. Dette kan omfatte kontrol af dataintegritet og datakryptering afhængigt af den underliggende sikkerhedsmekanisme.

3. GSS API-support i Java

Java understøtter GSS API som en del af pakken "org.ietf.jgss". Pakkenavnet kan virke ejendommeligt. Det er fordi Java-bindinger til GSS API er defineret i en IETF-specifikation. Specifikationen i sig selv er uafhængig af sikkerhedsmekanismen.

En af de populære sikkerhedsmekanismer for Java GSS er Kerberos v5.

3.1. Java GSS API

Lad os prøve at forstå nogle af de centrale API'er, der bygger Java GSS:

  • GSSContext indkapsler GSS API sikkerhedskontekst og leverer tjenester tilgængelige under konteksten
  • GSSCredential indkapsler GSS API-legitimationsoplysninger for en enhed, der er nødvendig for at etablere sikkerhedskonteksten
  • GSSnavn indkapsler GSS API-hovedenheden, som giver en abstraktion til forskellige navneområder, der bruges af underliggende mekanismer

Bortset fra ovenstående grænseflader er der få andre vigtige klasser at bemærke:

  • GSSManager fungerer som fabriksklasse for andre vigtige GSS API-klasser som f.eks GSSnavn, GSSCredentialog GSSContext
  • Oid repræsenterer de universelle objektidentifikatorer (OID'er), som er hierarkiske identifikatorer, der bruges i GSS API til at identificere mekanismer og navneformater
  • MessageProp indpakker egenskaber for at angive GSSContext på ting som Quality of Protection (QoP) og fortrolighed til dataudveksling
  • ChannelBinding indkapsler den valgfri kanalbindingsinformation, der bruges til at styrke kvaliteten, hvormed peer-entitetsgodkendelse leveres

3.2. Java GSS-sikkerhedsudbyder

Mens Java GSS definerer kernerammen for implementering af GSS API i Java, giver den ikke en implementering. Java vedtager Udbyder-baserede stikbare implementeringer til sikkerhedstjenester inklusive Java GSS.

Der kan være en eller flere sådanne sikkerhedsudbydere registreret hos Java Cryptography Architecture (JCA). Hver sikkerhedsudbyder kan implementere en eller flere sikkerhedstjenester som Java GSSAPI og sikkerhedsmekanismer nedenunder.

Der er en standard GSS-udbyder, der leveres med JDK. Der er dog andre leverandørspecifikke GSS-udbydere med forskellige sikkerhedsmekanismer, som vi kan bruge. En sådan udbyder er IBM Java GSS. Vi er nødt til at registrere en sådan sikkerhedsudbyder hos JCA for at kunne bruge dem.

Desuden, hvis det kræves, vi kan implementere vores egen sikkerhedsudbyder med muligvis tilpassede sikkerhedsmekanismer. Dette er dog næppe nødvendigt i praksis.

4. GSS API gennem et eksempel

Nu ser vi Java GSS i aktion gennem et eksempel. Vi opretter en simpel klient- og serverapplikation. Klienten kaldes mere almindeligt som initiator og server som acceptor i GSS. Vi bruger Java GSS og Kerberos v5 nedenunder til godkendelse.

4.1. GSS-kontekst til klient og server

Til at begynde med bliver vi nødt til det etablere en GSSContext, både på serveren og klientsiden af ansøgningen.

Lad os først se, hvordan vi kan gøre dette på klientsiden:

GSSManager manager = GSSManager.getInstance (); Streng serverPrinciple = "HTTP / [e-mail-beskyttet]"; GSSName servernavn = manager.createName (serverPrinciple, null); Oid krb5Oid = ny Oid ("1.2.840.113554.1.2.2"); GSSContext clientContext = manager.createContext (servernavn, krb5Oid, (GSSCredential) null, GSSContext.DEFAULT_LIFETIME); clientContext.requestMutualAuth (sand); clientContext.requestConf (sand); clientContext.requestInteg (true);

Der sker en hel del ting her, lad os nedbryde dem:

  • Vi begynder med at oprette en forekomst af GSSManager
  • Derefter bruger vi denne forekomst til at oprette GSSContext, forbi:
    • -en GSSnavn repræsenterer serverprincip, note det Kerberos-specifikke hovednavn her
    • det Oid af mekanisme til brug, Kerberos v5 her
    • initiativtagerens legitimationsoplysninger, nul her betyder, at standardoplysninger bruges
    • levetiden for den etablerede kontekst
  • Endelig forbereder vi os konteksten for gensidig godkendelse, fortrolighed og dataintegritet

På samme måde skal vi definere konteksten på serversiden:

GSSManager manager = GSSManager.getInstance (); GSSContext serverContext = manager.createContext ((GSSCredential) null);

Som vi kan se, er dette meget enklere end konteksten på klientsiden. Den eneste forskel her er, at vi har brug for acceptorens legitimationsoplysninger, som vi har brugt som nul. Som før, nul betyder, at standardoplysningerne bruges.

4.2. GSS API-godkendelse

Selvom vi har oprettet serveren og klientsiden GSSContext, bemærk, at de ikke er etableret på dette tidspunkt.

For at etablere disse sammenhænge er vi nødt til at udveksle tokens, der er specifikke for den angivne sikkerhedsmekanisme, dvs. Kerberos v5:

// På klientsiden clientToken = clientContext.initSecContext (ny byte [0], 0, 0); sendToServer (clientToken); // Dette skal sendes over netværket // På serversiden serverToken = serverContext.acceptSecContext (clientToken, 0, clientToken.length); sendToClient (serverToken); // Dette skal sendes over netværket // Tilbage på klientsiden clientContext.initSecContext (serverToken, 0, serverToken.length);

Dette gør endelig konteksten etableret i begge ender:

assertTrue (serverContext.isEstablished ()); assertTrue (clientContext.isEstablished ());

4.3. GSS API sikker kommunikation

Nu hvor vi har en kontekst etableret i begge ender, vi kan begynde at sende data med integritet og fortrolighed:

// På klientsiden byte [] messageBytes = "Baeldung" .getBytes (); MessageProp clientProp = ny MessageProp (0, sand); byte [] clientToken = clientContext.wrap (messageBytes, 0, messageBytes.length, clientProp); sendToClient (serverToken); // Dette skal sendes over netværket // På serversiden MessageProp serverProp = ny MessageProp (0, falsk); byte [] bytes = serverContext.unwrap (clientToken, 0, clientToken.length, serverProp); Strengstreng = ny streng (bytes); assertEquals ("Baeldung", streng);

Der er et par ting, der sker her, lad os analysere:

  • MessageProp bruges af klienten til at indstille indpakning metode og generere token
  • Metoden indpakning tilføjer også kryptografisk MIC af dataene, MIC'en er samlet som en del af tokenet
  • Dette token sendes til serveren (muligvis via et netværksopkald)
  • Serveren udnytter MessageProp igen for at indstille pakke ud metode og få data tilbage
  • Også metoden pakke ud verificerer MIC for de modtagne data og sikrer dataintegriteten

Derfor er klienten og serveren i stand til at udveksle data med integritet og fortrolighed.

4.4. Kerberos-opsætning til eksemplet

Nu, en GSS-mekanisme som Kerberos forventes typisk at hente legitimationsoplysninger fra en eksisterende Emne. Klassen Emne her er en JAAS-abstraktion, der repræsenterer en enhed som en person eller en tjeneste. Dette udfyldes normalt under en JAAS-baseret godkendelse.

For vores eksempel bruger vi dog ikke direkte en JAAS-baseret godkendelse. Vi lader Kerberos få legitimationsoplysninger direkte, i vores tilfælde ved hjælp af en keytab-fil. Der er en JVM-systemparameter for at opnå dette:

-Djavax.security.auth.useSubjectCredsOnly = falsk

Standardindstillingen Kerberos-implementering leveret af Sun Microsystem er dog afhængig af JAAS for at levere godkendelse.

Dette kan lyde i strid med det, vi lige har diskuteret. Bemærk, at vi eksplicit kan bruge JAAS i vores applikation, der udfylder Emne. Eller lad det være til den underliggende mekanisme for at autentificere direkte, hvor det alligevel bruger JAAS. Derfor er vi nødt til at levere en JAAS-konfigurationsfil til den underliggende mekanisme:

com.sun.security.jgss.initiate {com.sun.security.auth.module.Krb5LoginModule kræves useKeyTab = true keyTab = eksempel.keytab principal = "client / localhost" storeKey = true; }; com.sun.security.jgss.accept {com.sun.security.auth.module.Krb5LoginModule krævet useKeyTab = true keyTab = eksempel.keytab storeKey = true principal = "HTTP / localhost"; };

Denne konfiguration er ligetil, hvor vi har defineret Kerberos som det krævede login-modul til både initiator og acceptor. Derudover har vi konfigureret til at bruge de respektive hovedpersoner fra en keytab-fil. Vi kan videregive denne JAAS-konfiguration til JVM som en systemparameter:

-Djava.security.auth.login.config = login.conf

Her antages det, at vi har adgang til en Kerberos KDC. I KDC har vi oprettet de nødvendige principper og fået den keytab-fil, der skal bruges, lad os sige “Eksempel.keytab”.

Derudover har vi brug for Kerberos-konfigurationsfilen, der peger til højre KDC:

[libdefaults] default_realm = EXAMPLE.COM udp_preference_limit = 1 [realms] EXAMPLE.COM = {kdc = localhost: 52135}

Denne enkle konfiguration definerer en KDC, der kører på port 52135 med et standardområde som EXAMPLE.COM. Vi kan overføre dette til JVM som en systemparameter:

-Djava.security.krb5.conf = krb5.conf

4.5. Kører eksemplet

For at køre eksemplet skal vi gør brug af Kerberos-artefakter, der er diskuteret i sidste afsnit.

Vi skal også videregive de krævede JVM-parametre:

java -Djava.security.krb5.conf = krb5.conf \ -Djavax.security.auth.useSubjectCredsOnly = false \ -Djava.security.auth.login.config = login.conf \ com.baeldung.jgss.JgssUnitTest

Dette er tilstrækkeligt for Kerberos til at udføre godkendelsen med legitimationsoplysninger fra keytab og GSS for at etablere sammenhængene.

5. GSS API i den virkelige verden

Mens GSS API lover at løse et væld af sikkerhedsproblemer gennem plugbare mekanismer, er der få brugssager, der er blevet mere bredt vedtaget:

  • Det er det almindeligt anvendt i SASL som en sikkerhedsmekanisme, især hvor Kerberos er den underliggende valgmåde. Kerberos er en udbredt godkendelsesmekanisme, især inden for et virksomhedsnetværk. Det er virkelig nyttigt at udnytte en Kerberised infrastruktur til at godkende en ny applikation. Derfor overbygger GSS API dette hul pænt.
  • Det er det også anvendes i konjugation med SPNEGO at forhandle om en sikkerhedsmekanisme, når man ikke er kendt på forhånd. I denne henseende er SPNEGO en pseudomekanisme for GSS API på en måde. Dette understøttes bredt i alle moderne browsere, hvilket gør dem i stand til at udnytte Kerberos-baseret godkendelse.

6. GSS API i sammenligning

GSS API er ret effektiv til at levere sikkerhedstjenester til applikationer på en stikbar måde. Det er dog ikke det eneste valg at opnå dette i Java.

Lad os forstå, hvad Java ellers har at tilbyde, og hvordan sammenlignes de med GSS API:

  • Java Secure Socket Extension (JSSE): JSSE er et sæt pakker i Java, der implementerer Secure Sockets Layer (SSL) til Java. Det giver datakryptering, klient- og servergodkendelse og beskedintegritet. I modsætning til GSS API er JSSE afhængig af en PKI (Public Key Infrastructure) til at fungere. Derfor fungerer GSS API for at være mere fleksibel og let end JSSE.
  • Java Simple Authentication and Security Layer (SASL): SASL er en ramme for godkendelse og datasikkerhed for internetprotokoller som afkobler dem fra specifikke godkendelsesmekanismer. Dette har samme omfang som GSS API. Java GSS har dog begrænset support til underliggende sikkerhedsmekanismer gennem tilgængelige sikkerhedsudbydere.

Samlet set er GSS API ret stærk til at levere sikkerhedstjenester på agnostisk måde. Støtte til flere sikkerhedsmekanismer i Java vil dog tage dette længere ved vedtagelsen.

7. Konklusion

For at opsummere forstod vi i denne vejledning det grundlæggende i GSS API som en sikkerhedsramme. Vi gennemgik Java API til GSS og forstod, hvordan vi kan udnytte dem. I processen oprettede vi enkle klient- og serverkomponenter, der udførte gensidig godkendelse og udvekslede data sikkert.

Desuden så vi også, hvad der er de praktiske anvendelser af GSS API, og hvad er de tilgængelige alternativer i Java.

Som altid kan koden findes på GitHub.

Java bund

Jeg har lige annonceret det nye Lær foråret kursus med fokus på det grundlæggende i Spring 5 og Spring Boot 2:

>> KONTROLLER KURSEN

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