Ohjelmointi

Rakenna suojattuja verkkosovelluksia SSL: n ja JSSE API: n avulla

Internet on vaarallinen paikka. Suojaamattomia tietoja on yksinkertaisesti liian helppo piilottaa, huijata ja varastaa, kun se kulkee johtojen yli. Kirjoitin viime kuussa sarjan viimeisen artikkelin X.509-varmenteista ja julkisen avaimen infrastruktuurista (PKI) - tekniikoista, jotka takaavat suurimman osan verkkokaupan toiminnasta Internetissä. Artikkelin loppupuolella ehdotin SSL (Secure Socket Layer) -protokollan tutkimista, kuinka X.509-varmenteita käytetään käytännössä. SSL on X.509-tappajasovellus - lähes kaikki selaimet ja suosituimmat verkko- ja sovelluspalvelimet tukevat sitä.

Tässä kuussa tutkin SSL: ää, jonka JSSE (Java Secure Socket Extension) on toteuttanut, ja näytän sinulle, kuinka turvallisia verkkosovelluksia voidaan rakentaa Java-järjestelmään SSL: n ja JSSE: n avulla.

Aloitetaan yksinkertaisella esittelyllä. JSSE tarjoaa SSL-työkalupaketin Java-sovelluksille. Tarvittavien luokkien ja käyttöliittymien lisäksi JSSE tarjoaa kätevän komentorivin virheenkorjauskytkimen, jota voit käyttää katsella SSL-protokolla toiminnassa. Sen lisäksi, että työkalupakilla pelaaminen on hyödyllistä tietoa vakavan sovelluksen virheenkorjauksessa, se on erinomainen tapa saada jalkasi märiksi SSL: n ja JSSE: n avulla.

Esittelyn suorittamiseksi sinun on ensin koottava seuraava luokka:

 public class Test {public static void main (String [] arstring) {try {new java.net.URL ("//" + arstring [0] + "/"). getContent (); } saalis (poikkeuspoikkeus) {poikkeus.printStackTrace (); }}} 

Seuraavaksi sinun on otettava käyttöön SSL-virheenkorjaus ja suoritettava yllä oleva sovellus. Sovellus muodostaa yhteyden suojattuun verkkosivustoon, jonka määrität komentorivillä SSL-protokollaa käyttämällä HTTPS: n kautta. Ensimmäinen vaihtoehto lataa HTTPS-protokollan käsittelijän. Toinen vaihtoehto, virheenkorjaus, saa ohjelman tulostamaan käyttäytymisensä. Tässä on komento (korvaa suojatun verkkopalvelimen nimellä):

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

Sinun on asennettava JSSE; katso Resurssit, jos et ole varma miten.

Aloitetaan nyt asioista ja keskustellaan SSL: stä ja JSSE: stä.

Lyhyt katsaus SSL: ään

Johdannossa oleva koodi osoittaa helpoimman tavan lisätä SSL sovelluksiisi - java.net.URL luokassa. Tämä lähestymistapa on hyödyllinen, mutta ei tarpeeksi joustava, jotta voit luoda suojatun sovelluksen, joka käyttää yleisiä pistorasioita.

Ennen kuin näytän sinulle, kuinka lisätä tämä joustavuus, katsotaanpa nopeasti SSL: n ominaisuuksia.

Kuten nimestään käy ilmi, SSL pyrkii tarjoamaan sovelluksille suojatun socketin mukaisen työkalupakin. Ihannetapauksessa sen pitäisi olla helppo muuntaa tavallisia pistorasioita käyttävä sovellus SSL: ää käyttäväksi sovellukseksi.

SSL käsittelee kolme tärkeää turvallisuuskysymystä:

  1. Se tarjoaa todennuksen, joka auttaa varmistamaan valintaikkunaan osallistuvien tahojen laillisuuden.
  2. Se tarjoaa yksityisyyttä. SSL auttaa takaamaan, että kolmas osapuoli ei voi tulkita kahden yksikön välistä dialogia.
  3. Se säilyttää eheyden. Tarkistussumman kaltaisen MAC: n (viestin todennuskoodi) käyttö auttaa takaamaan, että kolmas osapuoli ei muokkaa kahden yksikön välistä valintaikkunaa.

SSL luottaa vahvasti sekä julkisen avaimen että salaisen avaimen salaukseen. Se käyttää salaisen avaimen salausta kahden sovelluksen välillä vaihdetun tiedon salaamiseen. SSL tarjoaa ihanteellisen ratkaisun, koska salaisen avaimen algoritmit ovat sekä turvallisia että nopeita. Julkisen avaimen salaus, joka on hitaampaa kuin salaisen avaimen salaus, on parempi valinta todennukseen ja avainten vaihtoon.

Sunin JSSE-referenssitoteutus sisältää kaiken tarvittavan tekniikan SSL: n lisäämiseksi sovelluksiin. Se sisältää RSA: n (Rivest-Shamir-Adleman) salaustuen - Internet-tietoturvan tosiasiallisen standardin. Se sisältää SSL 3.0: n - nykyisen SSL-standardin - ja TLS (Transport Layer Security) 1.0: n, seuraavan sukupolven SSL: n, käyttöönoton. JSSE tarjoaa myös joukon sovellusliittymiä suojattujen pistorasioiden luomiseen ja käyttämiseen.

JSSE-sovellusliittymä

Java-suojausarkkitehtuuri käyttää Tehdas suunnittelukuvio voimakkaasti. Aloittamattomille tehtaan suunnittelumallissa käytetään erityistä tehdas esineitä rakentamaan instansseja sen sijaan, että kutsuisi niiden rakentajia suoraan. (Katso Resurssit tehdasluokan eduista ja haitoista.)

JSSE: ssä kaikki alkaa tehtaalta; siellä on tehdas SSL-pistorasioille ja tehdas SSL-palvelinpistokkeille. Koska yleiset ja palvelinpistorasiat ovat jo melko tärkeitä Java-verkko-ohjelmoinnille, oletan, että tunnet nämä kaksi ja ymmärrät niiden roolit ja erot. Jos et ole, suosittelen poimia hyvän kirjan Java-verkko-ohjelmoinnista.

SSLSocketFactory

Menetelmät javax.net.ssl.SSLSocketFactory luokka jaetaan kolmeen luokkaan. Ensimmäinen koostuu yhdestä staattisesta menetelmästä, joka noutaa oletus SSL-pistorasiatehtaan: staattinen SocketFactory getDefault ().

Toinen luokka koostuu neljästä menetelmästä, jotka on peritty javax.net.SocketFactory joka peilaa neljä avainkonstruktoria, jotka löytyvät java.net. pistorasia luokka, ja yksi menetelmä, joka kääri olemassa olevan liitännän SSL-liitäntään. He kukin palauttavat SSL-liitännän:

  1. Socket createSocket (merkkijono-isäntä, int-portti)
  2. Socket createSocket (String-isäntä, int-portti, InetAddress clientHost, int clientPort)
  3. Socket createSocket (InetAddress-isäntä, int-portti)
  4. Socket createSocket (InetAddress-isäntä, int-portti, InetAddress clientHost, int clientPort)
  5. Socket createSocket (Socket-liitäntä, merkkijono-isäntä, int-portti, looginen autoClose)

Kolmannen luokan kaksi menetelmää palauttavat luettelon oletusarvoisesti käytössä olevista SSL-salauspaketeista ja täydellisen luettelon tuetuista SSL-salauspaketeista:

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

Salauspaketti on yhdistelmä salausalgoritmeja, jotka määrittävät tietyn SSL-yhteyden suojaustason. Salauspaketti määrittää, onko yhteys salattu, onko sisällön eheys varmistettu ja miten todennus tapahtuu.

SSLServerSocketFactory

Menetelmät javax.net.ssl.SSLServerSocketFactory luokka kuuluu samaan kolmeen luokkaan kuin SSLSocketFactory. Ensinnäkin on yksi staattinen menetelmä, joka hakee oletus SSL-palvelinpistorasian tehtaan: staattinen ServerSocketFactory getDefault ().

Menetelmät, jotka palauttavat SSL-palvelinpistorasiat, heijastavat java.net.ServerSocket luokka:

  1. ServerSocket createServerSocket (int-portti)
  2. ServerSocket createServerSocket (int-portti, int-tilanne)
  3. ServerSocket createServerSocket (int-portti, int-tilanne, InetAddress-osoite)

Lopuksi SSLServerSocketFactory sisältää kaksi menetelmää, jotka palauttavat oletusarvoisesti käytössä olevan salausluettelon ja tuettujen salausten luettelon, vastaavasti:

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

Toistaiseksi sovellusliittymä on melko yksinkertainen.

SSL-liitäntä

Asiat tulevat mielenkiintoisiksi javax.net.ssl.SSLSocket luokassa. Oletan, että olet jo perehtynyt sen vanhemman, Pistoke luokassa, joten keskityn menetelmiin, jotka tarjoavat SSL-toimintoja.

Kuten kaksi SSL-tehdasluokkaa, ensimmäiset alla luetellut menetelmät noutavat vastaavasti käytössä olevat ja tuetut SSL-salauspaketit. Kolmas menetelmä asettaa sallitut salauspaketit. Sovellus voi käyttää kolmatta operaatiota päivittämään tai alentamaan hyväksyttävän suojauksen aluetta, jonka sovellus sallii:

  1. Merkkijono [] getEnabledCipherSuites ()
  2. Merkkijono [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (String [] -sarjat)

Nämä kaksi tapaa selvittävät, pystyykö pistorasiaan luomaan uusia SSL-istuntoja, jotka ylläpitävät yhteyksien yksityiskohtia - kuten jaettu salainen avain - yhteyden välillä:

  1. looginen getEnableSessionCreation ()
  2. void setEnableSessionCreation (looginen lippu)

Seuraavat kaksi menetelmää määrittävät, vaatiiko pistorasia asiakastodennuksen. Menetelmillä on merkitystä vain, kun niitä käytetään palvelintilan pistorasioissa. Muista, että SSL-määrityksen mukaan asiakkaan todennus on valinnainen. Esimerkiksi useimmat verkkosovellukset eivät vaadi sitä:

  1. looginen getNeedClientAuth ()
  2. void setNeedClientAuth (looginen tarve)

Alla olevat menetelmät vaihtavat liitännän asiakastilasta palvelintilaan. Tämä vaikuttaa siihen, kuka aloittaa SSL-kättelyn ja kuka todistaa ensin:

  1. looginen getUseClientMode ()
  2. void setUseClientMode (looginen tila)

Menetelmä void startHandshake () pakottaa SSL-kädenpuristuksen. On mahdollista, mutta ei yleistä, pakottaa uusi kättelyoperaatio olemassa olevaan yhteyteen.

Menetelmä SSLSession getSession () noutaa SSL-istunnon. Sinun on harvoin käytettävä suoraan SSL-istuntoa.

Kaksi alla lueteltua tapaa lisäävät ja poistavat SSL-kädenpuristuskuuntelijaobjektin. Kädenpuristuskuuntelijaobjekti saa ilmoituksen aina, kun SSL-kättelyopetus suoritetaan pistorasiaan.

  1. void addHandshakeCompletedListener (HandshakeCompletedListener-kuuntelija)
  2. void removeHandshakeCompletedListener (HandshakeCompletedListener-kuuntelija)

SSLServerSocket

javax.net.ssl.SSLServerSocket luokka on samanlainen kuin javax.net.ssl.SSLSocket luokka; se ei vaadi paljon henkilökohtaista huomiota. Itse asiassa joukko menetelmiä javax.net.ssl.SSLServerSocket luokka on osajoukko menetelmiä javax.net.ssl.SSLSocket luokassa.

Kaksi ensimmäistä alla lueteltua menetelmää noutavat käytössä olevat ja tuetut SSL-salauspaketit. Kolmas menetelmä asettaa sallitun salauspaketin:

  1. Merkkijono [] getEnabledCipherSuites ()
  2. Merkkijono [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (String [] -sarjat)

Nämä kaksi tapaa hallitsevat, pystyykö palvelinpistoke luomaan uusia SSL-istuntoja vai ei:

  1. looginen getEnableSessionCreation ()
  2. void setEnableSessionCreation (Boolen lippu)

Seuraavat menetelmät määrittävät, vaativatko hyväksytyt pistorasiat asiakkaan todennuksen:

  1. looginen getNeedClientAuth ()
  2. void setNeedClientAuth (looginen lippu)

Alla olevat menetelmät muuttavat hyväksytyn pistorasian asiakastilasta palvelintilaan:

  1. looginen getUseClientMode ()
  2. void setUseClientMode (looginen lippu)

Yksinkertainen esimerkki

Jotta tämä työkalupakkiopetus olisi selkeämpi, olen sisällyttänyt yksinkertaisen palvelimen ja yhteensopivan asiakkaan lähdekoodin alla. Se on turvallinen muunnelma tyypillisestä kaikusovelluksesta, jonka monet tutustuttavat verkkotekstit tarjoavat.

Alla esitetty palvelin käyttää JSSE: tä luodakseen suojatun palvelinpistorasian. Se kuuntelee palvelinpistoketta suojattujen asiakkaiden yhteyksistä. Kun suoritat palvelinta, sinun on määritettävä käytettävä avainkeskus. Avaimenvarasto sisältää palvelimen varmenteen. Olen luonut yksinkertaisen avaimen, joka sisältää yhden varmenteen. (Katso Resurssit sertifikaatin lataamiseen.)

tuo java.io.InputStream; tuo java.io.InputStreamReader; tuo java.io.BufferedReader; tuo java.io.IOException; tuo javax.net.ssl.SSLSocket; tuo javax.net.ssl.SSLServerSocket; tuo javax.net.ssl.SSLServerSocketFactory; public class EchoServer {public static void main (String [] arstring) {kokeile {SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault (); SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket (9999); SSLSocket sslsocket = (SSLSocket) sslserversocket.accept (); InputStream inputstream = sslsocket.getInputStream (); InputStreamReader inputstreamreader = uusi InputStreamReader (inputstream); BufferedReader bufferedreader = uusi BufferedReader (inputstreamreader); Merkkijono = null; while ((merkkijono = puskuroitu lukija.readLine ())! = null) {System.out.println (merkkijono); System.out.flush (); }} saalis (poikkeuspoikkeus) {poikkeus.printStackTrace (); }}} 

Käynnistä palvelin seuraavalla komennolla (foobar on sekä avainvarastotiedoston nimi että sen salasana):

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

Alla esitetty asiakas käyttää JSSE: tä turvalliseen yhteyden muodostamiseen palvelimeen. Kun suoritat asiakasta, sinun on määritettävä käytettävä luottamus, joka sisältää luettelon luotettavista varmenteista. Olen luonut yksinkertaisen luottamuskaupan, joka sisältää yhden varmenteen. (Katso Resurssit sertifikaatin lataamiseen.)

tuo java.io.InputStream; tuo java.io.OutputStream; tuo java.io.InputStreamReader; tuo java.io.OutputStreamWriter; tuo java.io.BufferedReader; tuo java.io.BufferedWriter; tuo java.io.IOException; tuo javax.net.ssl.SSLSocket; tuo javax.net.ssl.SSLSocketFactory; public class EchoClient {public static void main (String [] arstring) {kokeile {SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault (); SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket ("paikallinen isäntä", 9999); InputStream inputstream = System.in; InputStreamReader inputstreamreader = uusi InputStreamReader (inputstream); BufferedReader bufferedreader = uusi BufferedReader (inputstreamreader); OutputStream outputstream = sslsocket.getOutputStream (); OutputStreamWriter outputstreamwriter = uusi OutputStreamWriter (outputstream); BufferedWriter bufferedwriter = uusi BufferedWriter (outputstreamwriter); Merkkijono = null; while ((string = puskuroitu lukija.readLine ())! = null) {puskuroitu kirjoittaja.write (merkkijono + '\ n'); puskuroitu kirjoittaja.flush (); }} saalis (poikkeuspoikkeus) {poikkeus.printStackTrace (); }}} 

Käynnistä asiakas seuraavalla komennolla (foobar on sekä truststore-tiedoston nimi että sen salasana):

 java -Djavax.net.ssl.trustStore = foobar -Djavax.net.ssl.trustStorePassword = foobar EchoClient