Programmēšana

Veidojiet drošas tīkla lietojumprogrammas, izmantojot SSL un JSSE API

Internets ir bīstama vieta. Braucot pa vadiem, vienkārši ir pārāk viegli izlaupīt, apmānīt un nozagt neaizsargātu informāciju. Pagājušajā mēnesī es uzrakstīju sērijas pēdējo rakstu par X.509 sertifikātiem un publiskās atslēgas infrastruktūru (PKI) - tehnoloģijām, kas visvairāk nodrošina e-komercijas darbību internetā. Raksta beigās es ierosināju apskatīt SSL (Secure Socket Layer) protokolu, lai uzzinātu, kā X.509 sertifikāti tiek izmantoti praksē. SSL ir X.509 killer lietotne - to atbalsta gandrīz katrs pārlūks un populārākie tīmekļa un lietojumprogrammu serveri.

Šomēnes es izpētīšu SSL, ko ieviesis JSSE (Java Secure Socket Extension), un parādīšu, kā veidot drošas tīkla lietojumprogrammas Java, izmantojot SSL un JSSE.

Sāksim ar vienkāršu demonstrāciju. JSSE nodrošina SSL rīku komplektu Java lietojumprogrammām. Papildus nepieciešamajām klasēm un saskarnēm JSSE nodrošina ērtu komandrindas atkļūdošanas slēdzi, kuru varat izmantot, lai skatīties SSL protokols darbībā. Papildus noderīgas informācijas sniegšanai nepakļāvīgas lietojumprogrammas atkļūdošanai, spēlēšana ar rīku komplektu ir lielisks veids, kā saslapināt kājas ar SSL un JSSE.

Lai palaistu demonstrāciju, vispirms jāapkopo šāda klase:

 public class Test {public static void main (String [] arstring) {try {new java.net.URL ("//" + arstring [0] + "/"). getContent (); } nozveja (izņēmuma izņēmums) {izņēmums.printStackTrace (); }}} 

Pēc tam jums jāieslēdz SSL atkļūdošana un jāpalaiž iepriekš minētā lietojumprogramma. Lietojumprogramma izveido savienojumu ar drošu vietni, kuru norādāt komandrindā, izmantojot SSL protokolu, izmantojot HTTPS. Pirmā opcija ielādē HTTPS protokola apstrādātāju. Otrā iespēja, atkļūdošanas opcija, liek programmai izdrukāt savu darbību. Lūk, komanda (aizstāt ar drošu Web servera nosaukumu):

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

Jums jāinstalē JSSE; atsaukties uz resursiem, ja neesat pārliecināts, kā to izdarīt.

Tagad ķeramies pie lietas un runājam par SSL un JSSE.

Īss ieskats SSL

Ievadā esošais kods parāda vienkāršāko veidu, kā pievienot SSL lietojumprogrammām, izmantojot java.net.URL klasē. Šī pieeja ir noderīga, taču nav pietiekami elastīga, lai ļautu jums izveidot drošu lietojumprogrammu, kurā tiek izmantotas vispārīgas kontaktligzdas.

Pirms parādīšu, kā pievienot šo elastību, ātri apskatīsim SSL funkcijas.

Kā norāda nosaukums, SSL mērķis ir nodrošināt lietojumprogrammas ar drošu, ligzdai līdzīgu rīkkopu. Ideālā gadījumā lietojumprogrammai, kas izmanto parastās kontaktligzdas, vajadzētu būt viegli pārveidot par lietojumprogrammu, kas izmanto SSL.

SSL risina trīs svarīgus drošības jautājumus:

  1. Tas nodrošina autentifikāciju, kas palīdz nodrošināt dialogā iesaistīto entītiju likumību.
  2. Tas nodrošina privātumu. SSL palīdz garantēt, ka trešā puse nevar atšifrēt dialogu starp divām entītijām.
  3. Tas saglabā integritāti. MAC (ziņojuma autentifikācijas koda) izmantošana, kas ir līdzīga kontrolsummai, palīdz garantēt, ka trešā puse nemaina dialogu starp divām entītijām.

SSL lielā mērā paļaujas gan uz publiskās atslēgas, gan uz slepenās atslēgas kriptogrāfiju. Tas izmanto slepenās atslēgas kriptogrāfiju, lai šifrētu datus, ar kuriem apmainās divas lietojumprogrammas. SSL nodrošina ideālu risinājumu, jo slepenās atslēgas algoritmi ir gan droši, gan ātri. Publiskās atslēgas kriptogrāfija, kas ir lēnāka nekā slepeno atslēgu kriptogrāfija, ir labāka izvēle autentifikācijai un atslēgu apmaiņai.

Sun JSSE atsauces ieviešana ir aprīkota ar visu nepieciešamo tehnoloģiju, lai SSL pievienotu lietojumprogrammām. Tas ietver RSA (Rivest-Shamir-Adleman) kriptogrāfijas atbalstu - de facto standartu drošībai internetā. Tas ietver SSL 3.0 - pašreizējā SSL standarta - un TLS (Transport Layer Security) 1.0 - nākamās paaudzes SSL - ieviešanu. JSSE nodrošina arī API komplektu, lai izveidotu un izmantotu drošas kontaktligzdas.

JSSE API

Java drošības arhitektūrā tiek izmantots Rūpnīca dizaina modelis stipri. Nezinātājiem rūpnīcas dizaina modelī tiek izmantoti īpaši rūpnīcā objektus, lai konstruētu instances, nevis izsauktu to konstruktorus tieši. (Skatiet resursus par rūpnīcas klases plusi un mīnusi.)

JSSE viss sākas ar rūpnīcu; tur ir SSL ligzdu rūpnīca un SSL serveru ligzdu rūpnīca. Tā kā vispārīgās kontaktligzdas un serveru ligzdas jau ir diezgan būtiskas Java tīkla programmēšanai, pieņemšu, ka jūs esat iepazinušies ar abiem un saprotat to lomu un atšķirības. Ja neesat, iesaku paņemt labu grāmatu par Java tīkla programmēšanu.

SSLSocketFactory

Metodes javax.net.ssl.SSLSocketFactory klase iedalās trīs kategorijās. Pirmais sastāv no vienas statiskas metodes, kas izgūst noklusējuma SSL ligzdu rūpnīcu: statiskā SocketFactory getDefault ().

Otro kategoriju veido četras no mantotās metodes javax.net.SocketFactory kas atspoguļo četrus galvenos konstruktorus, kas atrasti java.net.Socket klase un viena metode, kas ietin esošo ligzdu ar SSL ligzdu. Viņi katrs atgriež SSL ligzdu:

  1. Socket createSocket (virknes resursdators, int ports)
  2. Socket createSocket (virknes resursdators, int ports, InetAddress clientHost, int clientPort)
  3. Socket createSocket (InetAddress resursdators, int ports)
  4. Socket createSocket (InetAddress resursdators, int ports, InetAddress clientHost, int clientPort)
  5. Socket createSocket (ligzdas ligzda, virknes resursdators, int ports, Būla automātiskā aizvēršana)

Divas trešās kategorijas metodes atgriež to SSL šifru komplektu sarakstu, kuri pēc noklusējuma ir iespējoti, un pilnu atbalstīto SSL šifru komplektu sarakstu:

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

Šifrēšanas komplekts ir kriptogrāfisko algoritmu kombinācija, kas nosaka noteiktu SSL savienojuma drošības līmeni. Šifrēšanas komplekts nosaka, vai savienojums ir šifrēts, vai tiek pārbaudīta satura integritāte un kā notiek autentifikācija.

SSLServerSocketFactory

Metodes javax.net.ssl.SSLServerSocketFactory klase ietilpst tajās pašās trīs kategorijās kā SSLSocketFactory. Pirmkārt, ir viena statiska metode, kas izgūst noklusējuma SSL servera ligzdu rūpnīcu: statiskais ServerSocketFactory getDefault ().

Metodes, kas atgriež SSL servera ligzdas, atspoguļo java.net.ServerSocket klase:

  1. ServerSocket createServerSocket (int ports)
  2. ServerSocket createServerSocket (int ports, int kavējums)
  3. ServerSocket createServerSocket (int ports, int kavējums, InetAddress adrese)

Visbeidzot SSLServerSocketFactory piedāvā divas metodes, kas atgriež attiecīgi pēc noklusējuma iespējoto šifru sarakstu un atbalstīto šifru sarakstu:

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

Līdz šim API ir diezgan vienkārša.

SSL ligzda

Lietas kļūst interesantas javax.net.ssl.SSLSocket klasē. Es pieņemu, ka jūs jau esat iepazinies ar tā vecāku Kontaktligzda klasē, tāpēc es koncentrēšos uz metodēm, kas nodrošina ar SSL saistītu funkcionalitāti.

Tāpat kā divas SSL rūpnīcas klases, arī pirmās divas tālāk uzskaitītās metodes izgūst attiecīgi iespējotos un atbalstītos SSL šifru komplektus. Trešā metode nosaka iespējotos šifru komplektus. Lietojumprogramma var izmantot trešo darbību, lai jauninātu vai pazeminātu pieņemamās drošības diapazonu, ko lietojumprogramma ļaus:

  1. Virkne [] getEnabledCipherSuites ()
  2. Virkne [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (virknes [] komplekti)

Šīs divas metodes nosaka, vai ligzda var izveidot jaunas SSL sesijas, kurās starp savienojumiem tiek saglabāta detalizēta informācija par savienojumu:

  1. boolean getEnableSessionCreation ()
  2. void setEnableSessionCreation (Būla karogs)

Nākamās divas metodes nosaka, vai kontaktligzdai būs nepieciešama klienta autentifikācija. Metodēm ir jēga tikai tad, ja tās izsauc servera režīma ligzdās. Atcerieties, ka saskaņā ar SSL specifikāciju klienta autentifikācija nav obligāta. Piemēram, lielākajai daļai tīmekļa lietojumprogrammu tas nav nepieciešams:

  1. boolean getNeedClientAuth ()
  2. void setNeedClientAuth (Būla nepieciešamība)

Tālāk norādītās metodes maina kontaktligzdu no klienta režīma uz servera režīmu. Tas ietekmē to, kurš sāk SSL rokasspiedienu un kurš vispirms autentificē:

  1. boolean getUseClientMode ()
  2. void setUseClientMode (Būla režīms)

Metode void startHandshake () piespiež SSL rokasspiedienu. Ir iespējams, bet ne bieži, piespiest jaunu rokasspiediena darbību esošajā savienojumā.

Metode SSLSession getSession () izgūst SSL sesiju. Jums reti būs nepieciešams tieši piekļūt SSL sesijai.

Divas tālāk uzskaitītās metodes pievieno un noņem SSL rokasspiediena klausītāja objektu. Rokasspiediena klausītāja objekts tiek informēts ikreiz, kad ligzdā tiek pabeigta SSL rokasspiediena darbība.

  1. void addHandshakeCompletedListener (HandshakeCompletedListener klausītājs)
  2. void removeHandshakeCompletedListener (HandshakeCompletedListener klausītājs)

SSLServerSocket

The javax.net.ssl.SSLServerSocket klase ir līdzīga javax.net.ssl.SSLSocket klase; tas neprasa lielu individuālu uzmanību. Faktiski metožu kopa javax.net.ssl.SSLServerSocket klase ir metožu apakškopa javax.net.ssl.SSLSocket klasē.

Pirmās divas tālāk uzskaitītās metodes izgūst iespējotos un atbalstītos SSL šifra komplektus. Trešā metode nosaka iespējoto šifru komplektu:

  1. Virkne [] getEnabledCipherSuites ()
  2. Virkne [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (virknes [] komplekti)

Šīs divas metodes kontrolē, vai servera ligzda var izveidot jaunas SSL sesijas.

  1. boolean getEnableSessionCreation ()
  2. void setEnableSessionCreation (Būla karogs)

Šīs metodes nosaka, vai pieņemtajām ligzdām būs nepieciešama klienta autentifikācija:

  1. boolean getNeedClientAuth ()
  2. void setNeedClientAuth (Būla karogs)

Tālāk norādītās metodes maina pieņemto ligzdu no klienta režīma uz servera režīmu:

  1. boolean getUseClientMode ()
  2. void setUseClientMode (Būla karodziņš)

Vienkāršs piemērs

Lai padarītu šo rīkkopas apmācību skaidrāku, zemāk esmu iekļāvis vienkārša servera un saderīga klienta avota kodu. Tā ir droša varianta tipiskajai atbalss lietojumprogrammai, ko nodrošina daudzi tīkla ievadteksti.

Serveris, kas parādīts zemāk, izmanto JSSE, lai izveidotu drošu servera ligzdu. Tas servera ligzdā klausās savienojumus no drošiem klientiem. Palaižot serveri, jānorāda izmantojamā atslēgu krātuve. Atslēgu krātuve satur servera sertifikātu. Esmu izveidojis vienkāršu atslēgu krātuvi, kurā ir viens sertifikāts. (Skatiet sertifikāta lejupielādes resursus.)

importēt java.io.InputStream; importēt java.io.InputStreamReader; importēt java.io.BufferedReader; importēt java.io.IOException; importēt javax.net.ssl.SSLSocket; importēt javax.net.ssl.SSLServerSocket; importēt 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 = jauns InputStreamReader (inputstream); BufferedReader bufferedreader = jauns BufferedReader (inputstreamreader); Virknes virkne = null; while ((virkne = bufferedreader.readLine ())! = null) {System.out.println (virkne); System.out.flush (); }} nozveja (izņēmuma izņēmums) {izņēmums.printStackTrace (); }}} 

Izmantojiet šo komandu, lai palaistu serveri (foobar ir gan atslēgas veikala faila nosaukums, gan tā parole):

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

Tālāk parādītais klients izmanto JSSE, lai droši izveidotu savienojumu ar serveri. Palaižot klientu, jums jānorāda izmantojamais uzticamības veikals, kurā ir uzticamo sertifikātu saraksts. Esmu izveidojis vienkāršu uzticības veikalu, kurā ir viens sertifikāts. (Skatiet sertifikāta lejupielādes resursus.)

importēt java.io.InputStream; importēt java.io.OutputStream; importēt java.io.InputStreamReader; importēt java.io.OutputStreamWriter; importēt java.io.BufferedReader; importēt java.io.BufferedWriter; importēt java.io.IOException; importēt javax.net.ssl.SSLSocket; importēt 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 = jauns InputStreamReader (inputstream); BufferedReader bufferedreader = jauns BufferedReader (inputstreamreader); OutputStream outputstream = sslsocket.getOutputStream (); OutputStreamWriter outputstreamwriter = jauns OutputStreamWriter (outputstream); BufferedWriter bufferedwriter = jauns BufferedWriter (outputstreamwriter); Virknes virkne = null; while ((virkne = bufferedreader.readLine ())! = null) {bufferedwriter.write (virkne + '\ n'); bufferedwriter.flush (); }} nozveja (izņēmuma izņēmums) {izņēmums.printStackTrace (); }}} 

Izmantojiet šo komandu, lai palaistu klientu (foobar ir gan uzticamības faila nosaukums, gan tā parole):

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