Java savjet 96: Upotrijebite HTTPS u kodu Java klijenta

Ako ste ikad pokušali implementirati sigurnu komunikaciju između Java klijenta i HTTPS (HyperText Transfer Protocol Secure) poslužitelja, vjerojatno ste otkrili da standardna java.net.URLklasa ne podržava HTTPS protokol. Implementacija te jednadžbe na poslužitelju prilično je jednostavna. Gotovo svaki web poslužitelj koji je danas dostupan nudi mehanizam za traženje podataka pomoću HTTPS-a. Jednom kada postavite web poslužitelj, bilo koji preglednik može zatražiti sigurne podatke s vašeg poslužitelja jednostavnim određivanjem HTTPS-a kao protokola za URL. Ako još nemate postavljen HTTPS poslužitelj, možete testirati svoj klijentski kod s gotovo bilo kojom HTTPS web stranicom na Internetu. Odjeljak Resursi sadrži kratki popis kandidata koje možete koristiti u tu svrhu.

Iz perspektive klijenta, međutim, jednostavnost S na kraju poznatog HTTP-a obmanjuje. Preglednik zapravo obavlja znatnu količinu zakulisnih poslova kako bi osigurao da nitko nije miješao ili nadzirao informacije koje ste zatražili. Ispostavilo se da je algoritam za šifriranje za HTTPS patentiran od strane RSA Security (još barem nekoliko mjeseci). Korištenje tog algoritma licencirali su proizvođači preglednika, ali Sun Microsystems nije licencirao za uključivanje u standardnu URLimplementaciju Java klase. Kao rezultat toga, ako pokušate konstruirati URLobjekt sa nizom koji specificira HTTPS kao protokol, MalformedURLExceptionbacit će se a.

Srećom, kako bi se prilagodilo tom ograničenju, Java specifikacija omogućuje mogućnost odabira alternativnog rukovatelja toka za URLklasu. Međutim, tehnika potrebna za provedbu koja je različita, ovisno o virtualnom stroju (VM) koji koristite. Za Microsoftov VM, kompatibilan s JDK 1.1, JView, Microsoft je licencirao algoritam i pružio obradu HTTPS tokova kao dio svog wininetpaketa. S druge strane, Sun je nedavno objavio proširenje Java Secure Sockets Extension (JSSE) za VM kompatibilne s JDK 1.2, u kojem je Sun također licencirao i pružio HTTPS rukovatelj protokom. Ovaj će članak pokazati kako implementirati upotrebu obrađivača toka s omogućenim HTTPS-om, koristeći JSSE i Microsoftov wininetpaket.

JDK 1.2 kompatibilni virtualni strojevi

Tehnika upotrebe VM-a kompatibilnih s JDK 1.2 oslanja se prvenstveno na proširenje Java Secure Sockets (JSSE) 1.0.1. Da bi ta tehnika uspjela, morate instalirati JSSE i dodati ga na put klase dotičnog VM klijenta.

Nakon što instalirate JSSE, morate postaviti svojstvo sustava i dodati novog davatelja zaštite Securityobjektu klase. Postoje obje mogućnosti na različite načine, ali za potrebe ovog članka prikazana je programska metoda:

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

Nakon upućivanja prethodna dva poziva metode, MalformedURLExceptionviše se neće bacati pozivanjem sljedećeg koda:

 URL url = novi URL ("// [vaš poslužitelj]"); 

Ako se spajate na standardni SSL port, 443, imate mogućnost dodavanja broja porta u niz URL-a. Međutim, ako vaš web poslužitelj koristi nestandardni priključak za SSL promet, morat ćete dodati broj priključka u svoj URL niz ovako:

 URL url = novi URL ("// [vaš poslužitelj]: 7002"); 

Jedno upozorenje te tehnike odnosi se na URL koji se odnosi na poslužitelj koji ima nepotpisan ili nevažeći SSL certifikat. U tom će slučaju pokušaj dohvaćanja ulaznog ili izlaznog toka iz objekta veze URL-a baciti znak SSLExceptions porukom "nepouzdani cert-lanac poslužitelja". Ako poslužitelj ima valjani potpisan certifikat, neće se izuzeti iznimka.

URL url = novi URL ("// [vaš poslužitelj]"); URLConnection con = URL.openConnection (); // SSLException bačen ovdje ako je certifikat poslužitelja nevažeći con.getInputStream ();

Očito rješenje tog problema je dobivanje potpisanih certifikata za vaš poslužitelj. Međutim, jedan od sljedećih URL-ova također može pružiti rješenje: "Java Secure Socket Extension 1.0.2 Changes" (Sun Microsystems) ili Sun's Java Developer Connection forum.

Microsoft JView

Djelomično zbog kontinuiranog spora između Microsofta i Sunca oko licenciranja Jave za upotrebu na Windows platformama, Microsoft JView VM trenutno je samo u skladu s JDK 1.1. Stoga gore opisana tehnika neće raditi za klijente koji rade u JViewu, jer JSSE zahtijeva barem 1.2.2 kompatibilni VM. No, prikladno je da Microsoft nudi rukovatelj protokom s omogućenim HTTPS-om kao dio com.ms.net.wininetpaketa.

Obrađivač toka možete postaviti u JView okruženju pozivanjem jedne statičke metode na URLklasi:

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

Nakon upućivanja prethodnog poziva metode,

MalformedURLException

više se neće bacati pozivanjem sljedećeg koda:

 URL url = novi URL ("// [vaš poslužitelj]"); 

Dva su upozorenja povezana s tom tehnikom. Prvo, prema dokumentaciji JDK, setURLStreamHandlerFactorymetoda se može pozvati najviše jednom u danom VM-u. Naknadni pokušaji pozivanja te metode bacit će znak Error. Drugo, kao što je slučaj s rješenjem 1.2 VM, morate biti oprezni kada upotrebljavate URL koji se odnosi na poslužitelj s nepotpisanim ili nevaljanim SSL certifikatom. Kao i u prethodnom slučaju, problemi se javljaju kada se pokuša dohvatiti ulazni ili izlazni tok iz objekta veze URL-a. Međutim, umjesto da baci SSLException, obrađivač Microsoftovih tokova baca standard IOException.

URL url = novi URL ("// [vaš poslužitelj]"); URLConnection con = url.openConnection (); // IOException bačen ovdje ako je certifikat poslužitelja nevažeći con.getInputStream ();

Opet, očito je rješenje tog problema pokušaj HTTPS komunikacije samo s poslužiteljima koji imaju potpisan, valjan certifikat. Međutim, JView nudi još jednu mogućnost. Neposredno prije dohvaćanja ulaznog ili izlaznog toka iz objekta veze URL-a, možete nazvati setAllowUserInteraction(true)objekt povezivanja. To će uzrokovati da JView prikaže poruku koja upozorava korisnika da su certifikati poslužitelja nevaljani, ali daje mu mogućnost da svejedno nastavi. Međutim, imajte na umu da takve poruke mogu biti razumne za radnu površinu aplikacije, ali pojavljivanje dijaloških okvira na vašem poslužitelju za bilo što drugo osim za otklanjanje pogrešaka vjerojatno je neprihvatljivo.

Napomena: setAllowUserInteraction()Metodu možete pozvati i u VM-ima kompatibilnim s JDK 1.2. Međutim, pri korištenju Sunčeve 1.2 VM (s kojom je testiran ovaj kod), ne prikazuju se dijaloški okviri čak i kada je to svojstvo postavljeno na true.

URL url = novi URL ("// [vaš poslužitelj]"); URLConnection con = url.openConnection (); // uzrokuje da VM prikazuje dijaloški okvir pri povezivanju // s nepouzdanim poslužiteljima con.setAllowUserInteraction (true); con.getInputStream ();

com.ms.net.wininetPaket Čini se da je instaliran i postavljen na CLASSPATH sustava po defaultu u sustavu Windows NT 4.0, Windows 2000 i Windows 9x sustavima. Također, prema Microsoftovoj dokumentaciji JDK, WinInetStreamHandlerFactoryje "... isti rukovatelj koji je instaliran prema zadanim postavkama prilikom pokretanja apleta."

Neovisnost platforme

Iako obje ove tehnike koje sam opisao pokrivaju većinu platformi na kojima se vaš Java klijent može izvoditi, vaš Java klijent možda će trebati raditi na VM-ovima kompatibilnim s JDK 1.1 i JDK 1.2. "Napišite jednom, trčite bilo gdje", sjećate se? Ispostavilo se da je kombiniranje te dvije tehnike tako da se odgovarajući rukovatelj učitava ovisno o VM-u prilično jednostavan. Sljedeći kod pokazuje jedan način da se to postigne:

Niz strVendor = System.getProperty ("java.vendor"); Niz strVersion = System.getProperty ("java.version"); // Pretpostavlja sistemsku verziju niza oblika: //[major].[minor].[release] (npr. 1.2.2) Double dVersion = new Double (strVersion.substring (0, 3)); // Ako radimo u MS okruženju, upotrijebite rukovatelj MS streamom. if (-1 <strVendor.indexOf ("Microsoft")) {try {Class clsFactory = Class.forName ("com.ms.net.wininet.WininetStreamHandlerFactory"); if (null! = clsFactory) URL.setURLStreamHandlerFactory ((URLStreamHandlerFactory) clsFactory.newInstance ()); } catch (ClassNotFoundException cfe) {throw new Exception ("Nije moguće učitati obrađivač streama Microsoft SSL" + ". Provjeri classpath." + cfe.toString ());} // // Ako je tvornica rukovatelja streamom // već uspješno postavljena // provjerite je li postavljena naša zastavica i pojedite pogrešku (Error error) {m_bStreamHandlerSet = true;}} // Ako se nalazimo u normalnom Java okruženju, // pokušajte upotrijebiti obrađivač JSSE. // NAPOMENA: JSSE zahtijeva 1.2 ili bolji inačici if (1.2 <= dVersion.doubleValue ()) {System.setProperty ("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol "); probajte {// ako imamo dostupnog JSSE davatelja usluge //, a on još nije // postavljen, dodajte ga kao novu ponudu klasi sigurnosti. Razred clsFactory = Class.forName ("com.sun.net.ssl.internal.ssl.Provider"); if ((null! = clsFactory) && (null == Security.getProvider ("SunJSSE"))) Security.addProvider ((Provider) clsFactory.newInstance ());} catch (ClassNotFoundException cfe) {throw new Exception ("Nije moguće učitati obrađivač JSSE SSL toka." + "Provjeri put do klase." + cfe.toString ()); }}

Što je s apletima?

Izvođenje komunikacije temeljene na HTTPS-u iz apleta čini se prirodnim proširenjem gore opisanih scenarija. U stvarnosti je to u većini slučajeva još lakše. U 4.0 i novijim verzijama Netscape Navigatora i Internet Explorera HTTPS je prema zadanim postavkama omogućen za njihove odgovarajuće VM-ove. Stoga, ako želite stvoriti HTTPS vezu unutar koda apleta, jednostavno navedite HTTPS kao svoj protokol prilikom izrade instance URLklase:

 URL url = novi URL ("// [vaš poslužitelj]"); 

Ako klijentski preglednik koristi Sun-ov dodatak Java 2, tada postoje dodatna ograničenja kako možete koristiti HTTPS. Potpunu raspravu o korištenju HTTPS-a s dodatkom Java 2 možete pronaći na web mjestu Sun (pogledajte Resursi).

Zaključak

Korištenje HTTPS protokola između aplikacija može biti brz i učinkovit način za postizanje razumne razine sigurnosti u vašoj komunikaciji. Nažalost, čini se da su razlozi zbog kojih nije podržan kao dio standardne Java specifikacije više pravni nego tehnički. Međutim, pojavom JSSE-a i korištenjem Microsoftovog com.ms.net.winintpaketa, sigurna komunikacija moguća je s većine platformi sa samo nekoliko redaka koda.

Matt Towers, eBozo koji se sam opisao, nedavno je napustio svoju razvojnu poziciju s Visiom. Otada se pridružio internetskom pokretanju PredictPoint.com u Seattlu u saveznoj državi Washington, gdje radi kao stalni Java programer.

Saznajte više o ovoj temi

  • The source code zip file for this article contains the platform-independent code shown above implemented in a class called HttpsMessage. HttpsMessage is intended as a subclass to the HttpMessage class written by Jason Hunter, author of Java Servlet Programming (O'Reilly & Associates). Look for HttpsMessage in the upcoming second edition of his book. If you wish to use that class as intended, you'll need to download and install the com.oreilly.servlets package. The com.oreilly.servlets package and corresponding source code can be found on Hunter's Website

    //www.servlets.com

  • You can also download the source zip file

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

  • Here are a few good Webpages for testing HTTPS communication:
  • //www.verisign.com/
  • //happiness.dhs.org/
  • //www.microsoft.com
  • //www.sun.com
  • //www.ftc.gov
  • More information on the JSSE as well as the downloadable bits and installation instructions can be found on Sun's Website

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

  • A description of how to use some JSSE services, including the technique described above, can be found in "Secure Networking in Java" by Jonathan Knudsen on the O'Reilly Website

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

  • More information on WininetStreamHandlerFactory class can be found in the Microsoft JSDK documentation

    //www.microsoft.com/java/sdk/. In addition, the Microsoft knowledge base also publishes "PRBAllowing the URL class to access HTTPS in Applications"

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

  • For more information on using HTTPS with the Java 2 plug-in, see "How HTTPS Works in Java Plug-In" on Sun's Website

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

Ovu je priču "Java savjet 96: Upotrijebite HTTPS u kodu Java klijenta" izvorno objavio JavaWorld.