Programmering

Byg sikre netværksapplikationer med SSL og JSSE API

Internettet er et farligt sted. Det er simpelthen for let at snuse, spoofe og stjæle ubeskyttet information, når den bevæger sig over ledningerne. Sidste måned skrev jeg den sidste artikel i en serie om X.509-certifikater og offentlig nøgleinfrastruktur (PKI), de teknologier, der sikrer mest e-handelsaktivitet på Internettet. Nær slutningen af ​​artiklen foreslog jeg at se på SSL-protokollen (Secure Socket Layer) for at lære, hvordan X.509-certifikater bruges i praksis. SSL er X.509-killer-appen - næsten enhver browser og mest populære web- og applikationsservere understøtter den.

Denne måned vil jeg undersøge SSL som implementeret af JSSE (Java Secure Socket Extension) og vise dig, hvordan du opbygger sikre netværksapplikationer i Java ved hjælp af SSL og JSSE.

Lad os begynde med en simpel demonstration. JSSE leverer et SSL-værktøjssæt til Java-applikationer. Ud over de nødvendige klasser og grænseflader giver JSSE en praktisk kommandoliniedebugging-switch, som du kan bruge til holde øje SSL-protokollen i aktion. Ud over at give nyttige oplysninger til debugging af en modstridende applikation, er det at lege med værktøjssættet en god måde at få dine fødder våde med SSL og JSSE.

For at køre demonstrationen skal du først kompilere følgende klasse:

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

Dernæst skal du aktivere SSL-fejlretning og køre ovenstående applikation. Applikationen opretter forbindelse til det sikre websted, som du angiver på kommandolinjen ved hjælp af SSL-protokollen via HTTPS. Den første mulighed indlæser HTTPS-protokollbehandleren. Den anden mulighed, debug-indstillingen, får programmet til at udskrive dets adfærd. Her er kommandoen (udskift med navnet på en sikker webserver):

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

Du skal installere JSSE; se Ressourcer, hvis du er usikker på hvordan.

Lad os nu komme i gang og tale om SSL og JSSE.

Et kort kig på SSL

Koden i introduktionen viser den nemmeste måde at tilføje SSL til dine applikationer - via java.net.URL klasse. Denne tilgang er nyttig, men er ikke fleksibel nok til, at du kan oprette en sikker applikation, der bruger generiske stik.

Før jeg viser dig, hvordan du tilføjer denne fleksibilitet, lad os hurtigt se på SSL's funktioner.

Som navnet antyder, sigter SSL mod at give applikationer et sikkert stiklignende værktøjssæt. Ideelt set skal det være let at konvertere en applikation, der bruger almindelige sockets til en applikation, der bruger SSL.

SSL løser tre vigtige sikkerhedsproblemer:

  1. Det giver godkendelse, som hjælper med at sikre legitimiteten af ​​de enheder, der er involveret i en dialog.
  2. Det giver privatliv. SSL hjælper med at garantere, at en tredjepart ikke kan dechifrere dialogen mellem to enheder.
  3. Det opretholder integritet. Brug af en MAC (beskedgodkendelseskode), der svarer til et kontrolsum, hjælper med at garantere, at en dialog mellem to enheder ikke ændres af en tredjepart.

SSL er stærkt afhængig af både offentlig nøgle og hemmelig nøglekryptografi. Det bruger hemmelig nøglekryptografi til bulk-kryptering af de data, der udveksles mellem to applikationer. SSL giver den ideelle løsning, fordi algoritmer med hemmelige nøgler er både sikre og hurtige. Offentlig nøglekryptografi, som er langsommere end hemmelig nøglekryptografi, er et bedre valg til godkendelse og nøgleudveksling.

Suns JSSE-referenceimplementering leveres med al den teknologi, der er nødvendig for at tilføje SSL til dine applikationer. Det inkluderer RSA (Rivest-Shamir-Adleman) kryptografisupport - de facto-standarden for sikkerhed på Internettet. Det inkluderer en implementering af SSL 3.0 - den nuværende SSL-standard - og TLS (Transport Layer Security) 1.0, den næste generation af SSL. JSSE leverer også en række API'er til oprettelse og brug af sikre stikkontakter.

JSSE API

Java-sikkerhedsarkitekturen bruger Fabrik design mønster stærkt. For de uindviede bruger Factory design mønster specielt fabrik objekter til at konstruere forekomster, snarere end at kalde deres konstruktører direkte. (Se ressourcer til fordele og ulemper ved fabriksklassen.)

I JSSE begynder alt med fabrikken; der er en fabrik til SSL-sockets og en fabrik til SSL-server-sockets. Da generiske stik og serverstik allerede er ret grundlæggende for Java-netværksprogrammering, antager jeg, at du er fortrolig med de to, og at du forstår deres roller og forskelle. Hvis du ikke er det, anbefaler jeg, at du henter en god bog om Java-netværksprogrammering.

SSLSocketFactory

Metoder i javax.net.ssl.SSLSocketFactory klasse falder i tre kategorier. Den første består af en enkelt statisk metode, der henter standard SSL-stikket fabrik: statisk SocketFactory getDefault ().

Den anden kategori består af fire metoder arvet fra javax.net.SocketFactory der spejler de fire nøglekonstruktører, der findes på java.net.Socket klasse og en metode, der indpakker en eksisterende sokkel med en SSL-sokkel. De returnerer hver især et SSL-stik:

  1. Socket createSocket (String vært, int port)
  2. Socket createSocket (String vært, int port, InetAddress clientHost, int clientPort)
  3. Socket createSocket (InetAddress vært, int-port)
  4. Socket createSocket (InetAddress vært, int port, InetAddress clientHost, int clientPort)
  5. Socket createSocket (Socket socket, String vært, int port, boolsk autoClose)

De to metoder i den tredje kategori returnerer listen over SSL-krypteringspakker, der er aktiveret som standard, og den komplette liste over understøttede SSL-krypteringspakker:

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

En krypteringssuite er en kombination af kryptografiske algoritmer, der definerer et bestemt sikkerhedsniveau for en SSL-forbindelse. En krypteringssuite definerer, om forbindelsen er krypteret, om indholdsintegritet er verificeret, og hvordan godkendelse opstår.

SSLServerSocketFactory

Metoder til javax.net.ssl.SSLServerSocketFactory klasse falder i de samme tre kategorier som SSLSocketFactory. For det første er der den eneste statiske metode, der henter standard SSL-serverfabrikken: statisk ServerSocketFactory getDefault ().

Metoderne, der returnerer SSL-serverstik, spejler de konstruktører, der findes i java.net.ServerSocket klasse:

  1. ServerSocket createServerSocket (int-port)
  2. ServerSocket createServerSocket (int port, int backlog)
  3. ServerSocket createServerSocket (int-port, int-backlog, InetAddress-adresse)

Endelig blev SSLServerSocketFactory indeholder de to metoder, der returnerer henholdsvis listen over chifre, der er aktiveret og listen over understøttede chifre:

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

Indtil videre er API'en ret ligetil.

SSLSocket

Ting bliver interessante i javax.net.ssl.SSLSocket klasse. Jeg antager, at du allerede er bekendt med de metoder, der leveres af dets forælder, the Stikkontakt klasse, så jeg vil koncentrere mig om de metoder, der giver SSL-relateret funktionalitet.

Ligesom de to SSL-fabriksklasser henter de to første metoder, der er anført nedenfor, henholdsvis de aktiverede og understøttede SSL-krypteringspakker. Den tredje metode indstiller de aktiverede chifferpakker. En applikation kan bruge den tredje operation til at opgradere eller nedgradere rækkevidden af ​​acceptabel sikkerhed, som applikationen tillader:

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

Disse to metoder bestemmer, om soklen kan oprette nye SSL-sessioner, der opretholder forbindelsesdetaljer - som den delte hemmelige nøgle - mellem forbindelser:

  1. boolsk getEnableSessionCreation ()
  2. void setEnableSessionCreation (boolesk flag)

De næste to metoder bestemmer, om stikkontakten kræver klientgodkendelse. Metoderne giver kun mening, når de påberåbes på servertilstandsstik. Husk, i henhold til SSL-specifikationen er klientgodkendelse valgfri. For eksempel kræver de fleste webapplikationer det ikke:

  1. boolsk getNeedClientAuth ()
  2. void setNeedClientAuth (boolsk behov)

Metoderne nedenfor ændrer soklen fra klienttilstand til servertilstand. Dette påvirker, hvem der initierer SSL-håndtrykket, og hvem der først godkender:

  1. boolsk getUseClientMode ()
  2. ugyldigt setUseClientMode (boolsk tilstand)

Metode ugyldig startHandshake () tvinger et SSL-håndtryk. Det er muligt, men ikke almindeligt, at tvinge en ny håndtryksoperation i en eksisterende forbindelse.

Metode SSLSession getSession () henter SSL-sessionen. Du skal sjældent få adgang til SSL-sessionen direkte.

De to metoder, der er anført nedenfor, tilføjer og fjerner et SSL-håndtrykslytterobjekt. Handshake-lytterobjektet underrettes, hver gang en SSL-handshake-handling afsluttes på soklen.

  1. void addHandshakeCompletedListener (HandshakeCompletedListener lytter)
  2. ugyldig removeHandshakeCompletedListener (HandshakeCompletedListener lytter)

SSLServerSocket

Det javax.net.ssl.SSLServerSocket klasse ligner javax.net.ssl.SSLSocket klasse; det kræver ikke meget individuel opmærksomhed. Faktisk sæt af metoder til javax.net.ssl.SSLServerSocket klasse er en delmængde af metoderne på javax.net.ssl.SSLSocket klasse.

De første to metoder, der er anført nedenfor, henter de aktiverede og understøttede SSL-krypteringspakker. Den tredje metode indstiller den aktiverede chifferpakke:

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

Disse to metoder styrer, om serverbøsningen kan oprette nye SSL-sessioner eller ej:

  1. boolsk getEnableSessionCreation ()
  2. void setEnableSessionCreation (boolesk flag)

Følgende metoder bestemmer, om de accepterede sockets kræver klientgodkendelse:

  1. boolsk getNeedClientAuth ()
  2. void setNeedClientAuth (boolesk flag)

Metoderne nedenfor ændrer det accepterede stik fra klienttilstand til servertilstand:

  1. boolsk getUseClientMode ()
  2. ugyldigt setUseClientMode (boolesk flag)

Et simpelt eksempel

For at gøre dette værktøjssæt tutorial klarere, har jeg inkluderet kildekoden til en simpel server og en kompatibel klient nedenfor. Det er en sikker variation på den typiske ekko-applikation, som mange indledende netværkstekster giver.

Serveren, vist nedenfor, bruger JSSE til at oprette et sikkert serverstik. Det lytter på serverstikket efter forbindelser fra sikre klienter. Når du kører serveren, skal du angive den nøglelager, der skal bruges. Keystore indeholder serverens certifikat. Jeg har oprettet en simpel nøglelager, der indeholder et enkelt certifikat. (Se Ressourcer for at downloade certifikatet.)

importere java.io.InputStream; importere java.io.InputStreamReader; importere java.io.BufferedReader; importere java.io.IOException; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLServerSocket; import 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 = ny InputStreamReader (inputstream); BufferedReader bufferedreader = ny BufferedReader (inputstreamreader); Strengstreng = null; mens ((string = bufferedreader.readLine ())! = null) {System.out.println (string); System.out.flush (); }} fangst (undtagelsesundtagelse) {exception.printStackTrace (); }}} 

Brug følgende kommando til at starte serveren (foobar er både navnet på keystore-filen og dens adgangskode):

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

Klienten, vist nedenfor, bruger JSSE til sikkert at oprette forbindelse til serveren. Når du kører klienten, skal du angive den tillidsbutik, der skal bruges, og som indeholder listen over pålidelige certifikater. Jeg har oprettet en simpel tillidsbutik, der indeholder et enkelt certifikat. (Se Ressourcer for at downloade certifikatet.)

importere java.io.InputStream; importere java.io.OutputStream; importere java.io.InputStreamReader; importere java.io.OutputStreamWriter; importere java.io.BufferedReader; importere java.io.BufferedWriter; importere java.io.IOException; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; offentlig klasse 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 = ny InputStreamReader (inputstream); BufferedReader bufferedreader = ny BufferedReader (inputstreamreader); OutputStream outputstream = sslsocket.getOutputStream (); OutputStreamWriter outputstreamwriter = ny OutputStreamWriter (outputstream); BufferedWriter bufferedwriter = ny BufferedWriter (outputstreamwriter); Strengstreng = null; mens ((string = bufferedreader.readLine ())! = null) {bufferedwriter.write (string + '\ n'); bufferedwriter.flush (); }} fangst (undtagelsesundtagelse) {exception.printStackTrace (); }}} 

Brug følgende kommando til at starte klienten (foobar er både navnet på truststore-filen og dens adgangskode):

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