Programmering

Java Tip 96: Brug HTTPS i din Java-klientkode

Hvis du nogensinde har forsøgt at implementere sikker kommunikation mellem en Java-klient og en HTTPS-server (HyperText Transfer Protocol Secure), har du sandsynligvis opdaget, at standarden java.net.URL klasse understøtter ikke HTTPS-protokollen. Serversidens implementering af denne ligning er ret ligetil. Næsten enhver webserver, der er tilgængelig i dag, giver en mekanisme til anmodning om data ved hjælp af HTTPS. Når du har konfigureret din webserver, kan enhver browser anmode om sikker information fra din server ved blot at angive HTTPS som protokol for URL'en. Hvis du ikke allerede har oprettet en HTTPS-server, kan du teste din klientkode med næsten enhver HTTPS-webside på Internettet. Sektionen Ressourcer indeholder en kort liste over kandidater, som du kan bruge til dette formål.

Fra klientperspektivet bedrager imidlertid enkelheden af ​​S i slutningen af ​​den velkendte HTTP. Browseren udfører faktisk et betydeligt arbejde bag kulisserne for at sikre, at ingen har manipuleret med eller overvåget de oplysninger, du har anmodet om. Som det viser sig, er algoritmen til at foretage kryptering for HTTPS patenteret af RSA Security (i mindst et par måneder til). Brugen af ​​denne algoritme er licenseret af browserproducenter, men blev ikke licenseret af Sun Microsystems til at blive inkluderet i standard Java URL klasseimplementering. Som et resultat, hvis du forsøger at konstruere en URL objekt med en streng, der angiver HTTPS som protokol, a MisdannetURLE undtagelse vil blive kastet.

Heldigvis, for at imødekomme denne begrænsning, giver Java-specifikationen muligheden for at vælge en alternativ strømhåndterer til URL klasse. Den nødvendige teknik til implementering er imidlertid forskellig afhængigt af den virtuelle maskine (VM), du bruger. For Microsofts JDK 1.1-kompatible VM, JView, har Microsoft licenseret algoritmen og leveret en HTTPS-streamhandler som en del af dens wininet pakke. Sun har derimod for nylig frigivet Java Secure Sockets Extension (JSSE) til JDK 1.2-kompatible VM'er, hvor Sun også har licens og leveret en HTTPS-streamhåndtering. Denne artikel vil demonstrere, hvordan man implementerer brugen af ​​en HTTPS-aktiveret streamhåndterer ved hjælp af JSSE og Microsofts wininet pakke.

JDK 1.2-kompatible virtuelle maskiner

Teknikken til brug af JDK 1.2-kompatible VM'er er primært afhængig af Java Secure Sockets Extension (JSSE) 1.0.1. Før denne teknik fungerer, skal du installere JSSE og føje den til klassestien til den pågældende klient-VM.

Når du har installeret JSSE, skal du indstille en systemegenskab og tilføje en ny sikkerhedsudbyder til Sikkerhed klasse objekt. Der er en række forskellige måder at gøre begge disse ting på, men med henblik på denne artikel vises den programmatiske metode:

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

Efter at have foretaget de to foregående metodeopkald, MisdannetURLE undtagelse vil ikke længere blive kastet ved at ringe til følgende kode:

 URL url = ny URL ("// [din server]"); 

Hvis du opretter forbindelse til standard SSL-porten, 443, har du mulighed for at tilføje portnummeret til URL-strengen. Men hvis din webserver bruger en ikke-standard port til SSL-trafik, skal du tilføje portnummeret til din URL-streng sådan:

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

En advarsel ved denne teknik vedrører en URL, der henviser til en server, der har et usigneret eller ugyldigt SSL-certifikat. I så fald vil et forsøg på at hente input- eller outputstrømmen fra URL'ens forbindelsesobjekt kaste et SSLException med meddelelsen "ikke-betroet servercertkæde." Hvis serveren har et gyldigt, underskrevet certifikat, kastes der ingen undtagelse.

 URL url = ny URL ("// [din server]"); URLConnection con = URL.openConnection (); // SSLException kastes her, hvis servercertifikatet er ugyldigt con.getInputStream (); 

Den åbenlyse løsning på dette problem er at få signerede certifikater til din server. En af følgende webadresser kan dog også give en løsning: "Java Secure Socket Extension 1.0.2 Changes" (Sun Microsystems) eller Suns Java Developer Connection-forum.

Microsoft JView

Dels på grund af den igangværende tvist mellem Microsoft og Sun om licensering af Java til brug på Windows-platforme, er Microsoft JView VM i øjeblikket kun JDK 1.1-kompatibel. Derfor fungerer den ovenfor beskrevne teknik ikke for klienter, der kører i JView, da JSSE kræver mindst en 1.2.2-kompatibel VM. Praktisk nok leverer Microsoft dog en HTTPS-aktiveret streamhandler som en del af com.ms.net.wininet pakke.

Du kan indstille streamhandleren i et JView-miljø ved at kalde en enkelt statisk metode på URL klasse:

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

Efter at have foretaget det forrige metodeopkald,

MisdannetURLE undtagelse

vil ikke længere blive kastet ved at ringe til følgende kode:

 URL url = ny URL ("// [din server]"); 

Der er to forbehold forbundet med denne teknik. For det første ifølge JDK-dokumentationen er setURLStreamHandlerFactory metode kan kaldes højst en gang i en given VM. Efterfølgende forsøg på at kalde den metode vil kaste et Fejl. For det andet, som det er tilfældet med 1.2 VM-løsningen, skal du være forsigtig, når du bruger en URL, der henviser til en server med et usigneret eller ugyldigt SSL-certifikat. Som med det foregående tilfælde opstår der problemer, når der gøres et forsøg på at hente input- eller outputstrømmen fra URL'ens forbindelsesobjekt. Imidlertid i stedet for at smide en SSLException, Microsoft stream handler kaster en standard IOUndtagelse.

 URL url = ny URL ("// [din server]"); URLConnection con = url.openConnection (); // IOException kastes her, hvis servercertifikatet er ugyldigt con.getInputStream (); 

Igen er den åbenlyse løsning på dette problem kun at forsøge HTTPS-kommunikation med servere, der har et underskrevet, gyldigt certifikat. JView tilbyder dog en anden mulighed. Umiddelbart før du henter input- eller outputstrømmen fra URL-enes forbindelsesobjekt, kan du ringe setAllowUserInteraction (true) på forbindelsesobjektet. Det får JView til at vise en meddelelse, der advarer brugeren om, at serverens certifikater er ugyldige, men giver ham eller hende muligheden for at fortsætte alligevel. Husk dog, at sådanne meddelelser kan være rimelige for en desktop-applikation, men at dialogbokse vises på din server til andet end fejlfindingsformål er sandsynligvis uacceptabelt.

Bemærk: Du kan også ringe til setAllowUserInteraction () metode i JDK 1.2-kompatible VM'er. Ved brug af Suns 1.2 VM (som denne kode blev testet med) vises der imidlertid ingen dialoger, selv når denne egenskab er indstillet til sand.

 URL url = ny URL ("// [din server]"); URLConnection con = url.openConnection (); // får VM til at vise en dialog, når der oprettes forbindelse til // til ikke-tillid til servere con.setAllowUserInteraction (true); con.getInputStream (); 

Det com.ms.net.wininet pakken ser ud til at være installeret og placeret på systemets klasseban som standard på Windows NT 4.0-, Windows 2000- og Windows 9x-systemer. Ifølge Microsoft JDK-dokumentationen, WinInetStreamHandlerFactory er "... den samme handler, der er installeret som standard, når applets køres."

Platform uafhængighed

Selvom begge disse teknikker, jeg har beskrevet, dækker de fleste platforme, som din Java-klient kan køre på, skal din Java-klient muligvis køre på både JDK 1.1- og JDK 1.2-kompatible VM'er. "Skriv en gang, løb hvor som helst," husker du? Som det viser sig, er det ret ligetil at kombinere disse to teknikker, så den relevante handler indlæses afhængigt af den virtuelle computer. Den følgende kode demonstrerer en måde at gå om det på:

 Streng strVendor = System.getProperty ("java.vendor"); Streng strVersion = System.getProperty ("java.version"); // Antager en systemversionstreng af formularen: // [større]. [Mindre]. [Frigivelse] (f.eks. 1.2.2) Dobbelt dVersion = ny Dobbelt (strVersion.substring (0, 3)); // Hvis vi kører i et MS-miljø, skal du bruge MS-streamhandleren. hvis (-1 <strVendor.indexOf ("Microsoft")) {prøv {Class clsFactory = Class.forName ("com.ms.net.wininet.WininetStreamHandlerFactory"); hvis (null! = clsFactory) URL.setURLStreamHandlerFactory ((URLStreamHandlerFactory) clsFactory.newInstance ()); } catch (ClassNotFoundException cfe) {throw new Exception ("Kan ikke indlæse Microsoft SSL" + "stream handler. Kontroller classpath." + cfe.toString ()); } // Hvis strømhåndteringsfabrikken er // allerede er indstillet med succes // skal du sørge for, at vores flag er indstillet, og spis fejlfangsten (Fejlfejl) {m_bStreamHandlerSet = sand;}} // Hvis vi er i et normalt Java-miljø, // prøv at bruge JSSE-handler. // BEMÆRK: JSSE kræver 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-udbyderen tilgængelig, // og den ikke allerede er // indstillet, tilføj den som en ny forsyning til sikkerhedsklassen. Klasse clsFactory = Class.forName ("com.sun.net.ssl.internal.ssl.Provider"); hvis ((null! = clsFactory) && (null == Security.getProvider ("SunJSSE"))) Security.addProvider ((Provider) clsFactory.newInstance ()); } fange (ClassNotFoundException cfe) {throw new Exception ("Kan ikke indlæse JSSE SSL-streamhandleren." + "Kontroller classpath." + cfe.toString ()); }} 

Hvad med applets?

Udførelse af HTTPS-baseret kommunikation fra en applet virker som en naturlig udvidelse af scenarier beskrevet ovenfor. I virkeligheden er det endnu lettere i de fleste tilfælde. I 4.0 og nyere versioner af Netscape Navigator og Internet Explorer er HTTPS som standard aktiveret for deres respektive virtuelle computere. Derfor, hvis du vil oprette en HTTPS-forbindelse fra din appletkode, skal du blot angive HTTPS som din protokol, når du opretter en forekomst af URL klasse:

 URL url = ny URL ("// [din server]"); 

Hvis klientbrowseren kører Suns Java 2-plug-in, er der yderligere begrænsninger for, hvordan du kan bruge HTTPS. En komplet diskussion om brug af HTTPS med Java 2-plug-in findes på Suns websted (se Ressourcer).

Konklusion

Brug af HTTPS-protokollen mellem applikationer kan være en hurtig og effektiv måde at opnå et rimeligt niveau af sikkerhed i din kommunikation. Desværre synes grundene til, at det ikke understøttes som en del af standard Java-specifikationen, at være mere lovlige end tekniske. Men med fremkomsten af ​​JSSE og brugen af ​​Microsofts com.ms.net.winint pakke, er sikker kommunikation mulig fra de fleste platforme med kun et par kodelinjer.

Matt Towers, et selvbeskrevet eBozo, forlod for nylig sin udviklingsposition hos Visio. Han har siden været medlem af en internetstart, PredictPoint.com, i Seattle, Wash., Hvor han arbejder som Java-udvikler på fuld tid.

Lær mere om dette emne

  • Kildekoden zip-fil til denne artikel indeholder den platformuafhængige kode vist ovenfor implementeret i en klasse kaldet HttpsMeddelelse. HttpsMeddelelse er beregnet som en underklasse til HttpMessage klasse skrevet af Jason Hunter, forfatter af Java Servlet Programmering (O'Reilly & Associates). Lede efter HttpsMeddelelse i den kommende anden udgave af hans bog. Hvis du ønsker at bruge denne klasse som beregnet, skal du downloade og installere com.oreilly.servlets pakke. Det com.oreilly.servlets pakke og tilsvarende kildekode kan findes på Hunter's Website

    //www.servlets.com

  • Du kan også downloade zip-kildefilen

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

  • Her er et par gode websider til test af HTTPS-kommunikation:
  • //www.verisign.com/
  • //happiness.dhs.org/
  • //www.microsoft.com
  • //www.sun.com
  • //www.ftc.gov
  • Flere oplysninger om JSSE samt de bits, der kan downloades, og installationsinstruktioner kan findes på Suns websted

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

  • En beskrivelse af, hvordan man bruger nogle JSSE-tjenester, herunder teknikken beskrevet ovenfor, kan findes i "Secure Networking in Java" af Jonathan Knudsen på O'Reilly-webstedet

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

  • Flere oplysninger om WininetStreamHandlerFactory klasse kan findes i Microsoft JSDK-dokumentationen

    //www.microsoft.com/java/sdk/. Derudover offentliggør Microsoft-vidensbasen også "PRBA tillader URL-klassen at få adgang til HTTPS i applikationer"

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

  • For mere information om brug af HTTPS med Java 2-plug-in, se "Hvordan HTTPS fungerer i Java Plug-In" på Suns websted

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

Denne historie, "Java Tip 96: Brug HTTPS i din Java-klientkode" blev oprindeligt udgivet af JavaWorld.