Programmering

Java Tips 96: Bruk HTTPS i Java-klientkoden

Hvis du noen gang har prøvd å implementere sikker kommunikasjon mellom en Java-klient og en HTTPS-server (HyperText Transfer Protocol Secure), har du sannsynligvis oppdaget at standarden java.net.URL klasse støtter ikke HTTPS-protokollen. Serversidens implementering av ligningen er ganske grei. Nesten hvilken som helst webserver som er tilgjengelig i dag, gir en mekanisme for å be om data ved hjelp av HTTPS. Når du har konfigurert webserveren din, kan enhver nettleser be om sikker informasjon fra serveren din ved å spesifisere HTTPS som protokoll for URL-en. Hvis du ikke allerede har konfigurert en HTTPS-server, kan du teste klientkoden din med nesten hvilken som helst HTTPS-webside på Internett. Ressursdelen inneholder en kort liste over kandidater som du kan bruke til det formålet.

Fra klientperspektivet bedrager imidlertid enkelheten til S på slutten av den velkjente HTTP. Nettleseren gjør faktisk et betydelig arbeid bak kulissene for å sikre at ingen har tuklet med eller overvåket informasjonen du ba om. Som det viser seg, er algoritmen for å gjøre kryptering for HTTPS patentert av RSA Security (i minst noen måneder til). Bruken av denne algoritmen har blitt lisensiert av nettleserprodusenter, men ble ikke lisensiert av Sun Microsystems til å bli inkludert i standard Java URL klasseimplementering. Som et resultat, hvis du prøver å konstruere en URL objekt med en streng som spesifiserer HTTPS som protokoll, a MisdannetURLEeksepsjon vil bli kastet.

Heldigvis, for å imøtekomme den begrensningen, gir Java-spesifikasjonen muligheten til å velge en alternativ strømbehandler for URL klasse. Imidlertid er teknikken som kreves for å implementere en annen, avhengig av den virtuelle maskinen (VM) du bruker. For Microsofts JDK 1.1-kompatible VM, JView, har Microsoft lisensiert algoritmen og levert en HTTPS-strømbehandler som en del av wininet pakke. Sun, derimot, har nylig gitt ut Java Secure Sockets Extension (JSSE) for JDK 1.2-kompatible virtuelle maskiner, der Sun også har lisensiert og levert en HTTPS-strømhåndterer. Denne artikkelen vil demonstrere hvordan du implementerer bruken av en HTTPS-aktivert strømbehandler ved bruk av JSSE og Microsofts wininet pakke.

JDK 1.2-kompatible virtuelle maskiner

Teknikken for bruk av JDK 1.2-kompatible virtuelle maskiner er hovedsakelig avhengig av Java Secure Sockets Extension (JSSE) 1.0.1. Før den teknikken vil fungere, må du installere JSSE og legge den til i klassebanen til klienten VM.

Etter at du har installert JSSE, må du angi en systemegenskap og legge til en ny sikkerhetsleverandør til Sikkerhet klasseobjekt. Det er en rekke måter å gjøre begge disse tingene på, men i forbindelse med denne artikkelen vises den programmatiske metoden:

 System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.intern.www.protocol"); Security.addProvider (ny com.sun.net.ssl.internal.ssl.Provider ()); 

Etter å ha foretatt de to foregående metodeanropene, MisdannetURLEeksepsjon vil ikke lenger bli kastet ved å ringe følgende kode:

 URL url = ny URL ("// [serveren din" "); 

Hvis du kobler til standard SSL-port, 443, har du muligheten til å legge til portnummeret til URL-strengen. Imidlertid, hvis webserveren bruker en ikke-standard port for SSL-trafikk, må du legge til portnummeret til URL-strengen slik:

 URL url = ny URL ("// [serveren din: 7002"); 

En advarsel om denne teknikken gjelder en URL som refererer til en server som har et usignert eller ugyldig SSL-sertifikat. I så fall vil et forsøk på å hente inngangs- eller utgangsstrømmen fra URL-enes tilkoblingsobjekt kaste et SSLEksepsjon med meldingen "ikke-klarert servercertkjede." Hvis serveren har et gyldig, signert sertifikat, blir det ikke kastet noe unntak.

 URL url = ny URL ("// [serveren din" "); URLConnection con = URL.openConnection (); // SSLException kastet her hvis serversertifikatet er ugyldig con.getInputStream (); 

Den åpenbare løsningen på det problemet er å få signerte sertifikater for serveren din. Imidlertid kan en av følgende URL-er også gi en løsning: "Java Secure Socket Extension 1.0.2 Changes" (Sun Microsystems) eller Suns Java Developer Connection-forum.

Microsoft JView

På grunn av den pågående striden mellom Microsoft og Sun om lisensiering av Java for bruk på Windows-plattformer, er Microsoft JView VM for øyeblikket bare JDK 1.1-kompatibel. Derfor vil teknikken beskrevet ovenfor ikke fungere for klienter som kjører i JView, da JSSE krever minst en 1.2.2-kompatibel VM. Praktisk nok gir Microsoft imidlertid en HTTPS-aktivert strømbehandler som en del av com.ms.net.wininet pakke.

Du kan sette strømbehandleren i et JView-miljø ved å ringe en enkelt statisk metode på URL klasse:

 URL.setURLStreamHandlerFactory (ny com.ms.net.wininet.WininetStreamHandlerFactory ()); 

Etter å ha foretatt den forrige metodeanropet, blir

MisdannetURLE unntak

vil ikke lenger bli kastet ved å ringe følgende kode:

 URL url = ny URL ("// [serveren din" "); 

Det er to forbehold knyttet til den teknikken. For det første, ifølge JDK-dokumentasjonen, har setURLStreamHandlerFactory metoden kan kalles maksimalt en gang i en gitt VM. Påfølgende forsøk på å kalle den metoden vil kaste et Feil. For det andre, som tilfellet er med 1.2 VM-løsningen, må du være forsiktig når du bruker en URL som refererer til en server med et usignert eller ugyldig SSL-sertifikat. Som med forrige tilfelle, oppstår det problemer når det blir gjort et forsøk på å hente inngangs- eller utgangsstrømmen fra URL-enes tilkoblingsobjekt. Imidlertid, i stedet for å kaste en SSLEksepsjon, Microsoft stream handler kaster en standard IO Unntak.

 URL url = ny URL ("// [serveren din" "); URLConnection con = url.openConnection (); // IOException kastet her hvis serversertifikatet er ugyldig con.getInputStream (); 

Igjen, den åpenbare løsningen på det problemet er å forsøke HTTPS-kommunikasjon bare med servere som har et signert, gyldig sertifikat. Imidlertid tilbyr JView ett annet alternativ. Rett før du henter inngangs- eller utgangsstrømmen fra URL-enes tilkoblingsobjekt, kan du ringe setAllowUserInteraction (true) på tilkoblingsobjektet. Det vil føre til at JView viser en melding som advarer brukeren om at serverens sertifikater er ugyldige, men gir ham eller henne muligheten til å fortsette uansett. Husk imidlertid at slike meldinger kan være rimelige for et skrivebordsprogram, men det å ha dialogbokser vises på serveren din for noe annet enn feilsøkingsformål, er sannsynligvis uakseptabelt.

Merk: Du kan også ringe setAllowUserInteraction () metode i JDK 1.2-kompatible virtuelle maskiner. Imidlertid, når du bruker Suns 1.2 VM (som denne koden ble testet med), vises ingen dialoger selv når denne egenskapen er satt til sann.

 URL url = ny URL ("// [serveren din" "); URLConnection con = url.openConnection (); // får VM til å vise en dialog når du kobler // til ikke-klarerte servere con.setAllowUserInteraction (true); con.getInputStream (); 

De com.ms.net.wininet pakken ser ut til å være installert og plassert på systemets sti som standard på Windows NT 4.0, Windows 2000 og Windows 9x-systemer. I følge Microsoft JDK-dokumentasjonen, WinInetStreamHandlerFactory er "... den samme håndtereren som er installert som standard når du kjører appletter."

Plattformuavhengighet

Selv om begge disse teknikkene jeg har beskrevet dekker de fleste plattformene Java-klienten din kan kjøre på, kan det hende at Java-klienten din må kjøre på både JDK 1.1- og JDK 1.2-kompatible virtuelle maskiner. "Skriv en gang, løp hvor som helst," husker du? Som det viser seg, er det ganske greit å kombinere disse to teknikkene slik at riktig behandler lastes avhengig av VM. Følgende kode viser en måte å gå på det:

 Streng strVendor = System.getProperty ("java.vendor"); Streng strVersion = System.getProperty ("java.version"); // Antar en systemversjonsstreng av skjemaet: // [større]. [Mindre]. [Utgivelse] (f.eks. 1.2.2) Dobbel dVersion = ny Dobbel (strVersion.substring (0, 3)); // Hvis vi kjører i et MS-miljø, bruk MS-strømbehandling. hvis (-1 <strVendor.indexOf ("Microsoft")) {prøv {Class clsFactory = Class.forName ("com.ms.net.wininet.WininetStreamHandlerFactory"); hvis (null! = clsFactory) URL.setURLStreamHandlerFactory ((URLStreamHandlerFactory) clsFactory.newInstance ()); } fange (ClassNotFoundException cfe) {throw new Exception ("Kan ikke laste Microsoft SSL" + "stream handler. Sjekk classpath." + cfe.toString ()); } // Hvis strømhåndteringsfabrikken er // allerede vellykket satt // sørg for at flagget vårt er satt og spis feilfanget (Feilfeil) {m_bStreamHandlerSet = sant;}} // Hvis vi er i et normalt Java-miljø, // prøv å bruke JSSE-handler. // MERKNAD: JSSE krever 1.2 eller bedre hvis (1.2 <= dVersion.doubleValue ()) {System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol "); prøv {// hvis vi har JSSE-leverandøren tilgjengelig, // og den ikke allerede er // satt, legg den til som et nytt tilbud til sikkerhetsklassen. Klasse clsFactory = Class.forName ("com.sun.net.ssl.internal.ssl.Provider"); hvis ((null! = clsFactory) && (null == Security.getProvider ("SunJSSE"))) Security.addProvider ((Provider) clsFactory.newInstance ()); } catch (ClassNotFoundException cfe) {throw new Exception ("Unable to load the JSSE SSL stream handler." + "Check classpath." + cfe.toString ()); }} 

Hva med applets?

Å utføre HTTPS-basert kommunikasjon fra en applet virker som en naturlig utvidelse av scenariene beskrevet ovenfor. I virkeligheten er det enda enklere i de fleste tilfeller. I 4.0 og nyere versjoner av Netscape Navigator og Internet Explorer er HTTPS aktivert som standard for deres respektive virtuelle maskiner. Derfor, hvis du vil opprette en HTTPS-tilkobling fra appletkoden, bare spesifiser HTTPS som protokoll når du oppretter en forekomst av URL klasse:

 URL url = ny URL ("// [serveren din" "); 

Hvis klientleseren kjører Suns Java 2-plugin-modul, er det flere begrensninger for hvordan du kan bruke HTTPS. En fullstendig diskusjon om bruk av HTTPS med Java 2-programtillegget finner du på Suns nettsted (se Ressurser).

Konklusjon

Å bruke HTTPS-protokollen mellom applikasjoner kan være en rask og effektiv måte å oppnå et rimelig sikkerhetsnivå i kommunikasjonen din. Dessverre ser årsakene til at den ikke støttes som en del av standard Java-spesifikasjonen, å være mer lovlige enn tekniske. Imidlertid med fremkomsten av JSSE og bruk av Microsofts com.ms.net.winint pakke, er sikker kommunikasjon mulig fra de fleste plattformer med bare noen få kodelinjer.

Matt Towers, et selvbeskrevet eBozo, forlot nylig sin utviklingsposisjon hos Visio. Siden har han meldt seg inn i en internettoppstart, PredictPoint.com, i Seattle, Wash., Hvor han jobber som Java-utvikler på heltid.

Lær mer om dette emnet

  • Kildekoden zip-fil for denne artikkelen inneholder den plattformuavhengige koden vist ovenfor implementert i en klasse som heter HttpsMelding. HttpsMelding er ment som en underklasse til HttpMessage klasse skrevet av Jason Hunter, forfatter av Java Servlet Programmering (O'Reilly & Associates). Se etter HttpsMelding i den kommende andre utgaven av boka hans. Hvis du ønsker å bruke den klassen som tiltenkt, må du laste ned og installere com.oreilly.servlets pakke. De com.oreilly.servlets pakke og tilsvarende kildekode finner du på Hunter's Website

    //www.servlets.com

  • Du kan også laste ned kildens zip-fil

    //images.techhive.com/downloads/idge/imported/article/jvw/2000/06/httpsmessage.zip

  • Her er noen gode websider for testing av HTTPS-kommunikasjon:
  • //www.verisign.com/
  • //happiness.dhs.org/
  • //www.microsoft.com
  • //www.sun.com
  • //www.ftc.gov
  • Mer informasjon om JSSE samt nedlastbare biter og installasjonsinstruksjoner finner du på Suns nettsted

    //java.sun.com/products/jsse/.

  • En beskrivelse av hvordan du bruker noen JSSE-tjenester, inkludert teknikken beskrevet ovenfor, finner du i "Secure Networking in Java" av Jonathan Knudsen på O'Reilly-nettstedet.

    //java.oreilly.com/bite-size/java_1099.html

  • Mer informasjon om WininetStreamHandlerFactory klasse finner du i Microsoft JSDK-dokumentasjonen

    //www.microsoft.com/java/sdk/. I tillegg publiserer Microsoft kunnskapsbase "PRBAllowing the URL class to access HTTPS in Applications"

    //support.microsoft.com/support/kb/articles/Q191/1/20.ASP

  • For mer informasjon om bruk av HTTPS med Java 2-plugin-modulet, se "Hvordan HTTPS fungerer i Java Plug-In" på Suns nettsted

    //java.sun.com/products/plugin/1.2/docs/https.html

Denne historien, "Java Tips 96: Bruk HTTPS i Java-klientkoden", ble opprinnelig utgitt av JavaWorld.

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