Programavimas

Kurkite saugias tinklo programas naudodami SSL ir JSSE API

Internetas yra pavojinga vieta. Keliaujant laidais, tiesiog per lengva apgauti, apgauti ir pavogti neapsaugotą informaciją. Praėjusį mėnesį parašiau paskutinį serijos straipsnį apie X.509 sertifikatus ir viešojo rakto infrastruktūrą (PKI) - technologijas, užtikrinančias didžiausią elektroninės prekybos veiklą internete. Netoli straipsnio pabaigos aš pasiūliau pažvelgti į SSL („Secure Socket Layer“) protokolą, kad sužinotumėte, kaip X.509 sertifikatai naudojami praktiškai. SSL yra „X.509“ žudikų programa - ją palaiko beveik visos naršyklės ir populiariausi interneto ir programų serveriai.

Šį mėnesį tyrinėsiu SSL, kurį įgyvendino JSSE („Java Secure Socket Extension“), ir parodysiu, kaip kurti saugias tinklo programas „Java“ naudojant SSL ir JSSE.

Pradėkime nuo paprastos demonstracijos. JSSE pateikia SSL įrankių rinkinį „Java“ programoms. Be būtinų klasių ir sąsajų, JSSE pateikia patogų komandų eilutės derinimo jungiklį, kurį galite naudoti norėdami žiūrėti SSL protokolas veikia. Žaidimų su įrankių rinkiniu teikimas yra ne tik naudingos informacijos, leidžiančios derinti nepaklusnią programą, bet ir puikus būdas sušlapinti kojas naudojant SSL ir JSSE.

Norėdami paleisti demonstraciją, pirmiausia turite sudaryti šią klasę:

 viešosios klasės testas {public static void main (String [] strings) {try {new java.net.URL ("//" + arstring [0] + "/"). getContent (); } sugauti (Išimties išimtis) {išimtis.printStackTrace (); }}} 

Tada turite įjungti SSL derinimą ir paleisti aukščiau nurodytą programą. Programa prisijungia prie saugios svetainės, kurią nurodote komandinėje eilutėje naudodami SSL protokolą per HTTPS. Pirmoji parinktis įkelia HTTPS protokolo tvarkytuvą. Antroji parinktis, derinimo parinktis, priverčia programą atspausdinti savo elgesį. Štai komanda (pakeisti su saugaus interneto serverio pavadinimu):

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

Turite įdiegti JSSE; žr. šaltinius, jei nesate tikri, kaip tai padaryti.

Dabar leiskimės į reikalą ir pakalbėkime apie SSL ir JSSE.

Trumpas žvilgsnis į SSL

Įvado kodas parodo lengviausią būdą pridėti SSL prie savo programų per java.net.URL klasė. Šis metodas yra naudingas, tačiau nėra pakankamai lankstus, kad galėtumėte sukurti saugią programą, naudojančią bendruosius lizdus.

Prieš parodydamas, kaip pridėti tą lankstumą, greitai apžvelkime SSL funkcijas.

Kaip rodo jo pavadinimas, SSL siekia suteikti programoms saugų į lizdą panašų įrankių rinkinį. Idealiu atveju turėtų būti lengva konvertuoti programą, naudojančią įprastus lizdus, ​​į programą, naudojančią SSL.

SSL sprendžia tris svarbias saugumo problemas:

  1. Tai suteikia autentifikavimą, kuris padeda užtikrinti dialoge dalyvaujančių subjektų teisėtumą.
  2. Tai suteikia privatumo. SSL padeda garantuoti, kad trečioji šalis negali iššifruoti dialogo tarp dviejų subjektų.
  3. Tai palaiko vientisumą. MAC (pranešimo autentifikavimo kodo), panašaus į kontrolinę sumą, naudojimas padeda garantuoti, kad dialogo tarp dviejų subjektų nekeis trečioji šalis.

SSL labai priklauso nuo viešojo rakto ir slapto rakto kriptografijos. Jis naudoja slapto rakto kriptografiją, kad masiniu būdu užšifruotų duomenis, kuriais keičiamasi tarp dviejų programų. SSL yra idealus sprendimas, nes slapto rakto algoritmai yra saugūs ir greiti. Viešojo rakto kriptografija, kuri yra lėtesnė nei slapto rakto kriptografija, yra geresnis pasirinkimas tapatybei patvirtinti ir keistis raktais.

„Sun“ JSSE informacinis diegimas apima visas technologijas, reikalingas SSL pridėti prie jūsų programų. Tai apima RSA („Rivest-Shamir-Adleman“) kriptografijos palaikymą - de facto saugumo internete standartą. Tai apima SSL 3.0 - dabartinio SSL standarto - ir TLS (Transport Layer Security) 1.0, naujos SSL kartos, įgyvendinimą. JSSE taip pat pateikia API rinkinį, skirtą saugiems lizdams kurti ir naudoti.

JSSE API

„Java“ saugumo architektūroje naudojamas Gamykla dizaino modelis labai. Neišmanantiems fabriko dizaino šablone naudojami specialūs gamykla objektus konstruoti egzempliorius, o ne tiesiogiai skambinti jų konstruktoriams. (Žr. Šaltinius, kuriuose pateikiami gamyklos klasės privalumai ir trūkumai.)

JSSE viskas prasideda nuo gamyklos; yra SSL lizdų gamykla ir SSL serverių lizdų gamykla. Kadangi bendrieji ir serverio lizdai jau yra gana svarbūs programuojant „Java“ tinklą, manysiu, kad jūs abu esate susipažinę ir suprantate jų vaidmenis bei skirtumus. Jei ne, rekomenduoju pasiimti gerą knygą apie „Java“ tinklo programavimą.

„SSLSocketFactory“

Metodai javax.net.ssl.SSLSocketFactory klasė skirstoma į tris kategorijas. Pirmasis susideda iš vieno statinio metodo, pagal kurį gaunama numatytoji SSL lizdo gamykla: statinis „SocketFactory getDefault“ ().

Antrąją kategoriją sudaro keturi paveldėti metodai javax.net.SocketFactory kad atspindi keturis pagrindinius konstruktorius, rastus java.net.Socket klasės, ir vienas metodas, kuris apgaubia esamą lizdą SSL lizdu. Kiekvienas iš jų grąžina SSL lizdą:

  1. „Socket createSocket“ (styginių pagrindinis kompiuteris, int prievadas)
  2. „Socket createSocket“ (eilučių pagrindinis kompiuteris, „int“ prievadas, „InetAddress“ kliento priegloba, „int clientPort“)
  3. „Socket createSocket“ („InetAddress“ kompiuteris, int prievadas)
  4. „Socket createSocket“ („InetAddress“ pagrindinis kompiuteris, „int“ prievadas, „InetAddress“ kliento priegloba, „int clientPort“)
  5. „Socket createSocket“ („Socket“ lizdas, „String“ kompiuteris, int prievadas, loginis automatinis uždarymas)

Du trečios kategorijos metodai pateikia SSL šifravimo rinkinių, kurie yra įjungti pagal numatytuosius nustatymus, sąrašą ir visą palaikomų SSL šifravimo programų sąrašą:

  1. Eilutė [] getDefaultCipherSuites ()
  2. Stygos [] getSupportedCipherSuites ()

Šifruotas rinkinys yra kriptografinių algoritmų, apibrėžiančių tam tikrą SSL ryšio saugumo lygį, derinys. Šifruotas rinkinys apibrėžia, ar ryšys yra užšifruotas, ar patikrinamas turinio vientisumas ir kaip atliekamas autentifikavimas.

SSLServerSocketFactory

Metodai javax.net.ssl.SSLServerSocketFactory klasė patenka į tas pačias tris kategorijas kaip SSLSocketFactory. Pirma, yra vienas statinis metodas, pagal kurį gaunama numatytoji SSL serverio lizdo gamykla: statinis ServerSocketFactory getDefault ().

Metodai, kurie grąžina SSL serverio lizdus, ​​atspindi konstruktorius, esančius java.net.ServerSocket klasė:

  1. ServerSocket createServerSocket (int prievadas)
  2. „ServerSocket“ createServerSocket („int port“, „int backlog“)
  3. „ServerSocket“ createServerSocket („int port“, „int backlog“, „InetAddress“ adresas)

Galiausiai SSLServerSocketFactory yra du metodai, kurie pateikia pagal numatytuosius nustatymus įgalintų šifrų ir palaikomų šifrų sąrašą:

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

Iki šiol API yra gana paprasta.

SSL lizdas

Dalykai tampa įdomūs javax.net.ssl.SSLSocket klasė. Manau, kad jūs jau esate susipažinę su jos tėvų pateiktais metodais Lizdas klasę, todėl daugiausia dėmesio skirsiu metodams, kurie teikia su SSL susijusias funkcijas.

Kaip ir dvi SSL gamyklos klasės, pirmieji du toliau išvardyti metodai gauna atitinkamai įgalintus ir palaikomus SSL šifro paketus. Trečiasis metodas nustato įgalintus šifro paketus. Programa gali naudoti trečiąją operaciją, kad atnaujintų ar sumažintų priimtino saugumo diapazoną, kurį leis programa:

  1. Stygos [] getEnabledCipherSuites ()
  2. Stygos [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (eilutės [] komplektai)

Šie du metodai nustato, ar lizdas gali sukurti naujas SSL sesijas, kuriose palaikoma išsami ryšio informacija, pvz., Bendras slaptas raktas, tarp ryšių:

  1. loginis „getEnableSessionCreation“ ()
  2. void setEnableSessionCreation (loginė vėliava)

Kiti du metodai nustato, ar lizdui reikės kliento autentifikavimo. Metodai turi prasmę tik tada, kai jie iškviečiami serverio režimo lizduose. Atminkite, kad pagal SSL specifikaciją kliento autentifikavimas yra neprivalomas. Pavyzdžiui, daugumai žiniatinklio programų to nereikia:

  1. loginis „getNeedClientAuth“ ()
  2. void setNeedClientAuth (loginis poreikis)

Žemiau pateikti metodai pakeičia lizdą iš kliento režimo į serverio režimą. Tai turi įtakos tam, kas inicijuoja SSL paspaudimą ir kas pirmiausia patvirtina:

  1. loginis „getUseClientMode“ ()
  2. void setUseClientMode (loginis režimas)

Metodas negaliojanti pradžiaRankos paspaudimas () priverčia SSL rankos paspaudimą. Galima, bet ne įprasta, priversti naują rankos paspaudimo operaciją esamame ryšyje.

Metodas SSLSession getSession () gauna SSL sesiją. Jums retai reikės tiesiogiai prisijungti prie SSL sesijos.

Du toliau išvardyti metodai prideda ir pašalina SSL rankų paspaudimų klausytojo objektą. Apie paspaudimo klausytojo objektą pranešama, kai ant lizdo baigiama SSL rankos paspaudimo operacija.

  1. void addHandshakeCompletedListener („HandshakeCompletedListener“ klausytojas)
  2. void removeHandshakeCompletedListener („HandshakeCompletedListener“ klausytojas)

SSLServerSocket

javax.net.ssl.SSLServerSocket klasė yra panaši į javax.net.ssl.SSLSocket klasė; tam nereikia didelio individualaus dėmesio. Tiesą sakant, metodų rinkinys javax.net.ssl.SSLServerSocket klasė yra metodų pogrupis javax.net.ssl.SSLSocket klasė.

Pirmieji du toliau išvardyti metodai nuskaito įgalintus ir palaikomus SSL šifro paketus. Trečiasis metodas nustato įgalintą šifro rinkinį:

  1. Stygos [] getEnabledCipherSuites ()
  2. Stygos [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (eilutės [] komplektai)

Šie du metodai kontroliuoja, ar serverio lizdas gali sukurti naujas SSL sesijas, ar ne:

  1. loginis „getEnableSessionCreation“ ()
  2. void setEnableSessionCreation (loginė vėliava)

Šie metodai nustato, ar priimtiems lizdams reikės kliento autentifikavimo:

  1. loginis „getNeedClientAuth“ ()
  2. void setNeedClientAuth (loginė vėliava)

Toliau pateikiami metodai pakeičia priimtą lizdą iš kliento režimo į serverio režimą:

  1. loginis „getUseClientMode“ ()
  2. void setUseClientMode (loginė vėliava)

Paprastas pavyzdys

Kad šis įrankių rinkinys būtų aiškesnis, toliau pateikiu paprasto serverio ir suderinamo kliento šaltinio kodą. Tai saugus tipinės aido programos variantas, kurį teikia daugelis įžanginių tinklo tekstų.

Žemiau pateiktas serveris naudoja JSSE saugiam serverio lizdui sukurti. Jis klauso serverio lizdo, kaip prisijungti iš saugių klientų. Vykdydami serverį, turite nurodyti naudojamą raktų saugyklą. Raktų saugykloje yra serverio sertifikatas. Sukūriau paprastą raktų saugyklą, kurioje yra vienas sertifikatas. (Žr. Ištekliai, kaip atsisiųsti sertifikatą.)

importuoti java.io.InputStream; importuoti java.io.InputStreamReader; importuoti java.io.BufferedReader; importuoti java.io.IOException; importuoti javax.net.ssl.SSLSocket; importuoti javax.net.ssl.SSLServerSocket; importuoti javax.net.ssl.SSLServerSocketFactory; public class 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 = new InputStreamReader (inputstream); BufferedReader bufferedreader = naujas BufferedReader (inputstreamreader); Eilučių eilutė = null; while ((string = bufferedreader.readLine ())! = null) {System.out.println (eilutė); System.out.flush (); }} sugauti (Išimties išimtis) {Išimtis.printStackTrace (); }}} 

Norėdami paleisti serverį, naudokite šią komandą (foobar yra raktų saugyklos failo pavadinimas ir slaptažodis):

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

Žemiau pateiktas klientas naudoja JSSE saugiai prisijungti prie serverio. Vykdydami klientą, turite nurodyti naudojamą patikimumo saugyklą, kurioje yra patikimų sertifikatų sąrašas. Sukūriau paprastą patikėjimo centrą, kuriame yra vienas sertifikatas. (Žr. Ištekliai, kaip atsisiųsti sertifikatą.)

importuoti java.io.InputStream; importuoti java.io.OutputStream; importuoti java.io.InputStreamReader; importuoti java.io.OutputStreamWriter; importuoti java.io.BufferedReader; importuoti java.io.BufferedWriter; importuoti java.io.IOException; importuoti javax.net.ssl.SSLSocket; importuoti javax.net.ssl.SSLSocketFactory; public class 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 = new InputStreamReader (inputstream); BufferedReader bufferedreader = naujas BufferedReader (inputstreamreader); OutputStream outputstream = sslsocket.getOutputStream (); OutputStreamWriter outputstreamwriter = naujas OutputStreamWriter (outputstream); BufferedWriter bufferedwriter = naujas BufferedWriter (outputstreamwriter); Eilučių eilutė = null; while ((string = bufferedreader.readLine ())! = null) {bufferedwriter.write (eilutė + '\ n'); bufferedwriter.flush (); }} sugauti (Išimties išimtis) {išimtis.printStackTrace (); }}} 

Norėdami paleisti klientą, naudokite šią komandą (foobar yra patikimos parduotuvės failo pavadinimas ir slaptažodis):

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