Programiranje

Z SSL in API-jem JSSE gradite varne omrežne aplikacije

Internet je nevarno mesto. Preprosto je vohljati, ponarejati in krasti nezaščitene informacije, ko potujejo po žicah. Prejšnji mesec sem v seriji napisal zadnji članek o certifikatih X.509 in infrastrukturi javnih ključev (PKI), tehnologijah, ki zagotavljajo večino dejavnosti e-trgovine na internetu. Na koncu članka sem predlagal, da si ogledam protokol SSL (Secure Socket Layer) in se naučim, kako se potrdila X.509 uporabljajo v praksi. SSL je ubijalska aplikacija X.509 - podpirajo jo skoraj vsi brskalniki in najbolj priljubljeni spletni in aplikacijski strežniki.

Ta mesec bom raziskal SSL, kot ga izvaja JSSE (Java Secure Socket Extension), in vam pokazal, kako z uporabo SSL in JSSE zgraditi varne omrežne aplikacije v Javi.

Začnimo s preprostim prikazom. JSSE ponuja nabor orodij SSL za aplikacije Java. JSSE poleg potrebnih razredov in vmesnikov ponuja tudi priročno stikalo za odpravljanje napak v ukazni vrstici, s katerim lahko pazi protokol SSL v akciji. Poleg zagotavljanja koristnih informacij za odpravljanje napak v nepopustljivi aplikaciji je igranje s kompletom orodij odličen način, da si namočite noge s SSL in JSSE.

Če želite zagnati predstavitev, morate najprej prevesti naslednji razred:

 preizkus javnega razreda {public static void main (String [] arstring) {try {new java.net.URL ("//" + arstring [0] + "/"). getContent (); } catch (izjema izjema) {exception.printStackTrace (); }}} 

Nato morate vklopiti odpravljanje napak SSL in zagnati zgornjo aplikacijo. Program se poveže z varnim spletnim mestom, ki ga določite v ukazni vrstici, s protokolom SSL prek HTTPS. Prva možnost naloži vodnik protokola HTTPS. Druga možnost, možnost odpravljanja napak, povzroči, da program natisne svoje vedenje. Tu je ukaz (zamenjaj z imenom varnega spletnega strežnika):

 java -Djava.protocol.handler.pkgs = com.sun.net.ssl.internal.www.protocol -Djavax.net.debug = ssl Test 

Namestiti morate JSSE; glejte Vire, če niste prepričani, kako.

Zdaj pa se lotimo posla in se pogovorimo o SSL in JSSE.

Kratek pogled na SSL

Koda v uvodu prikazuje najlažji način dodajanja SSL v aplikacije - prek java.net.URL razred. Ta pristop je koristen, vendar ni dovolj prilagodljiv, da bi lahko ustvaril varno aplikacijo, ki uporablja generične vtičnice.

Preden vam pokažem, kako dodati to prilagodljivost, si na hitro oglejmo funkcije SSL.

Kot že ime pove, želi SSL aplikacijam zagotoviti varen komplet orodij, podobnih vtičnicam. V idealnem primeru bi moralo biti enostavno pretvoriti aplikacijo, ki uporablja običajne vtičnice, v aplikacijo, ki uporablja SSL.

SSL obravnava tri pomembna varnostna vprašanja:

  1. Omogoča preverjanje pristnosti, kar pomaga zagotoviti legitimnost entitet, vključenih v pogovorno okno.
  2. Zagotavlja zasebnost. SSL zagotavlja, da tretja oseba ne more razvozlati dialoga med dvema entitetama.
  3. Ohranja integriteto. Uporaba MAC (koda za preverjanje pristnosti sporočil), ki je podobna kontrolni vsoti, pomaga zagotoviti, da pogovornega okna med dvema entitetama ne bo spreminjala tretja oseba.

SSL se močno opira na kriptografijo z javnimi in tajnimi ključi. Za množično šifriranje podatkov, izmenjanih med dvema programoma, uporablja kriptografijo s tajnimi ključi. SSL je idealna rešitev, saj so algoritmi s skrivnimi ključi varni in hitri. Kriptografija z javnimi ključi, ki je počasnejša od kriptografije s tajnimi ključi, je boljša izbira za preverjanje pristnosti in izmenjavo ključev.

Sun-ova referenčna izvedba JSSE je opremljena z vso tehnologijo, potrebno za dodajanje SSL v vaše aplikacije. Vključuje podporo za kriptografijo RSA (Rivest-Shamir-Adleman) - de facto standard za varnost v internetu. Vključuje izvajanje SSL 3.0 - trenutni standard SSL - in TLS (Transport Layer Security) 1.0, naslednjo generacijo SSL. JSSE ponuja tudi nabor API-jev za ustvarjanje in uporabo varnih vtičnic.

API JSSE

Zaščitna arhitektura Java uporablja Tovarna močno oblikovati vzorec. Za nepoznavalce se v vzorcu tovarniške zasnove uporabljajo posebne tovarna predmete za konstruiranje primerkov, namesto da neposredno pokličejo njihove konstruktorje. (Za prednosti in slabosti tovarniškega razreda glejte Viri.)

V JSSE se vse začne s tovarno; obstaja tovarna za SSL vtičnice in tovarna za SSL vtičnice. Ker so generične vtičnice in vtičnice za strežnike že zelo pomembne za mrežno programiranje Java, predvidevam, da jih poznate in razumete njihove vloge in razlike. Če niste, priporočam, da vzamete v roke dobro knjigo o programiranju omrežja Java.

SSLSocketFactory

Metode v javax.net.ssl.SSLSocketFactory razred spadajo v tri kategorije. Prva je sestavljena iz ene same statične metode, ki pridobi privzeto tovarno vtičnice SSL: statična SocketFactory getDefault ().

Drugo kategorijo sestavljajo štiri metode, podedovane od javax.net.SocketFactory ki zrcalijo štiri ključne konstruktorje, najdene na java.net.Vtičnica razreda in ena metoda, ki obstoječo vtičnico ovije z vtičnico SSL. Vsak vrne vtičnico SSL:

  1. Socket createSocket (niz gostitelja, int vrata)
  2. Socket createSocket (niz gostitelja, int vrata, InetAddress clientHost, int clientPort)
  3. Socket createSocket (gostitelj InetAddress, int vrata)
  4. Socket createSocket (gostitelj InetAddress, int vrata, InetAddress clientHost, int clientPort)
  5. Socket createSocket (vtičnica vtičnice, niz gostitelja, int vrata, logično samodejno zapiranje)

Oba načina v tretji kategoriji vrneta seznam paketov SSL šifre, ki so privzeto omogočeni, in celoten seznam podprtih paketov šifer SSL:

  1. String [] getDefaultCipherSuites ()
  2. String [] getSupportedCipherSuites ()

Šifrant je kombinacija kriptografskih algoritmov, ki določajo določeno stopnjo varnosti za SSL povezavo. Zbirka šifer določa, ali je povezava šifrirana, ali je preverjena celovitost vsebine in kako poteka preverjanje pristnosti.

SSLServerSocketFactory

Metode na javax.net.ssl.SSLServerSocketFactory razred spadajo v iste tri kategorije kot SSLSocketFactory. Najprej obstaja ena statična metoda, ki pridobi privzeto tovarno vtičnice SSL strežnika: statični ServerSocketFactory getDefault ().

Metode, ki vrnejo vtičnice strežnika SSL, zrcalijo konstruktorje, najdene v java.net.ServerSocket razred:

  1. ServerSocket createServerSocket (int vrata)
  2. ServerSocket createServerSocket (int port, int backlog)
  3. ServerSocket createServerSocket (int vrata, int zaostanki, naslov InetAddress)

Končno, SSLServerSocketFactory vsebuje dve metodi, ki vrneta seznam privzeto omogočenih šifer in seznam podprtih šifer:

  1. String [] getDefaultCipherSuites ()
  2. String [] getSupportedCipherSuites ()

Zaenkrat je API precej preprost.

SSLSocket

Stvari postanejo zanimive v javax.net.ssl.SSLSocket razred. Predvidevam, da že poznate metode, ki jih ponuja njegov nadrejeni, Vtičnica razreda, zato se bom osredotočil na metode, ki zagotavljajo funkcionalnost, povezano s SSL.

Tako kot dva tovarniška razreda SSL tudi prva dva spodaj navedena načina pridobita omogočeni in podprti zbirki šifre SSL. Tretja metoda nastavi omogočene zbirke šifer. Aplikacija lahko s tretjo operacijo nadgradi ali zniža obseg sprejemljive varnosti, ki jo omogoča aplikacija:

  1. String [] getEnabledCipherSuites ()
  2. String [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (niz [] suite)

Ti dve metodi določita, ali lahko vtičnica vzpostavi nove seje SSL, ki med povezavami ohranjajo podrobnosti o povezavi - na primer skupni tajni ključ:

  1. boolean getEnableSessionCreation ()
  2. void setEnableSessionCreation (logična zastavica)

Naslednji dve metodi določita, ali bo vtičnica zahtevala preverjanje pristnosti odjemalca. Metode so smiselne le, če jih pokličete v vtičnicah strežniškega načina. Ne pozabite, da v skladu s specifikacijo SSL overjanje odjemalca ni obvezno. Na primer, večina spletnih aplikacij tega ne zahteva:

  1. boolean getNeedClientAuth ()
  2. void setNeedClientAuth (logična potreba)

Spodnje metode spremenijo vtičnico iz odjemalskega v strežniški način. To vpliva na to, kdo sproži stiskanje SSL in kdo najprej preveri pristnost:

  1. boolean getUseClientMode ()
  2. void setUseClientMode (logični način)

Metoda void startHandshake () prisili SSL stisk. Možno je, vendar ni pogosto, izsiliti novo operacijo rokovanja v obstoječi povezavi.

Metoda SSLSession getSession () pridobi sejo SSL. Redko boste morali neposredno dostopati do seje SSL.

Spodaj navedeni metodi dodajata in odstranjujeta objekt poslušalca stiskanja SSL. Objekt poslušalca stiskanja je obveščen vsakič, ko se na vtičnici zaključi operacija stiskanja SSL.

  1. void addHandshakeCompletedListener (poslušalec HandshakeCompletedListener)
  2. void removeHandshakeCompletedListener (poslušalec HandshakeCompletedListener)

SSLServerSocket

The javax.net.ssl.SSLServerSocket razred je podoben javax.net.ssl.SSLSocket razred; ne zahteva veliko individualne pozornosti. Dejansko je nabor metod na javax.net.ssl.SSLServerSocket razred je podskupina metod v javax.net.ssl.SSLSocket razred.

Spodnji dve metodi spodaj pridobita omogočeni in podprti paket šifrirnih SSL. Tretja metoda nastavi omogočeno zbirko šifer:

  1. String [] getEnabledCipherSuites ()
  2. String [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (niz [] suite)

Ti dve metodi nadzorujeta, ali lahko vtičnica strežnika vzpostavi nove seje SSL ali ne:

  1. boolean getEnableSessionCreation ()
  2. void setEnableSessionCreation (logična zastavica)

Naslednje metode določajo, ali bodo sprejete vtičnice zahtevale preverjanje pristnosti odjemalca:

  1. boolean getNeedClientAuth ()
  2. void setNeedClientAuth (logična zastavica)

Spodnje metode spremenijo sprejeto vtičnico iz odjemalskega v strežniški način:

  1. logična getUseClientMode ()
  2. void setUseClientMode (logična zastavica)

Preprost primer

Da bo ta vadnica orodij jasnejša, sem spodaj vključil izvorno kodo za preprost strežnik in združljivega odjemalca. To je varna različica tipične aplikacije za odmev, ki jo nudi veliko uvodnih besedil o omrežju.

Strežnik, prikazan spodaj, uporablja JSSE za ustvarjanje varne vtičnice strežnika. V vtičnici strežnika posluša povezave varnih odjemalcev. Med zagonom strežnika morate določiti shrambo ključev, ki jo želite uporabiti. Shramba ključev vsebuje strežniško potrdilo. Ustvaril sem preprosto shrambo ključev, ki vsebuje eno potrdilo. (Glejte Viri za prenos certifikata.)

uvoz java.io.InputStream; uvoz java.io.InputStreamReader; import java.io.BufferedReader; import java.io.IOException; uvoz javax.net.ssl.SSLSocket; uvoz javax.net.ssl.SSLServerSocket; uvoz javax.net.ssl.SSLServerSocketFactory; javni razred EchoServer {public static void main (String [] arstring) {try {SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault (); SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket (9999); SSLSocket sslsocket = (SSLSocket) sslserversocket.accept (); InputStream inputstream = sslsocket.getInputStream (); InputStreamReader inputstreamreader = nov InputStreamReader (inputstream); BufferedReader bufferedreader = nov BufferedReader (inputstreamreader); Niz niza = null; while ((string = bufferedreader.readLine ())! = nič) {System.out.println (string); System.out.flush (); }} catch (izjema izjema) {exception.printStackTrace (); }}} 

Za zagon strežnika uporabite naslednji ukaz (foobar je ime datoteke shrambe ključev in njeno geslo):

 java -Djavax.net.ssl.keyStore = foobar -Djavax.net.ssl.keyStorePassword = foobar EchoServer 

Stranka, prikazana spodaj, uporablja JSSE za varno povezavo s strežnikom. Med zagonom odjemalca morate določiti trgovino zaupanja, ki jo želite uporabiti, ki vsebuje seznam zaupanja vrednih potrdil. Ustvaril sem preprosto trgovino zaupanja, ki vsebuje eno potrdilo. (Glejte Viri za prenos certifikata.)

uvoz java.io.InputStream; import java.io.OutputStream; uvoz java.io.InputStreamReader; uvoz java.io.OutputStreamWriter; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; uvoz javax.net.ssl.SSLSocket; uvoz javax.net.ssl.SSLSocketFactory; javni razred EchoClient {public static void main (String [] arstring) {try {SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault (); SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket ("localhost", 9999); InputStream inputstream = System.in; InputStreamReader inputstreamreader = nov InputStreamReader (inputstream); BufferedReader bufferedreader = nov BufferedReader (inputstreamreader); OutputStream outputstream = sslsocket.getOutputStream (); OutputStreamWriter outputstreamwriter = nov OutputStreamWriter (outputstream); BufferedWriter bufferedwriter = nov BufferedWriter (outputstreamwriter); Niz niza = null; while ((string = bufferedreader.readLine ())! = null) {bufferedwriter.write (string + '\ n'); buffedwriter.flush (); }} catch (izjema izjema) {exception.printStackTrace (); }}} 

Za zagon odjemalca uporabite naslednji ukaz (foobar je ime datoteke zaupanja vrednega skladišča in njeno geslo):

 java -Djavax.net.ssl.trustStore = foobar -Djavax.net.ssl.trustStorePassword = foobar EchoClient 
$config[zx-auto] not found$config[zx-overlay] not found