Programování

Vytvářejte zabezpečené síťové aplikace pomocí protokolu SSL a rozhraní JSSE API

Internet je nebezpečné místo. Je prostě příliš snadné snoopovat, spoofovat a ukrást nechráněné informace, když se šíří po drátech. Minulý měsíc jsem napsal poslední článek v sérii o certifikátech X.509 a infrastruktuře veřejných klíčů (PKI), technologiích, které zajišťují většinu aktivit elektronického obchodování na internetu. Na konci článku jsem navrhl podívat se na protokol SSL (Secure Socket Layer) a zjistit, jak se certifikáty X.509 používají v praxi. SSL je aplikace zabijáka X.509 - podporuje ji téměř každý prohlížeč a nejoblíbenější webové a aplikační servery.

Tento měsíc prozkoumám SSL implementované v JSSE (Java Secure Socket Extension) a ukážu vám, jak vytvářet bezpečné síťové aplikace v Javě pomocí SSL a JSSE.

Začněme jednoduchou ukázkou. JSSE poskytuje sadu nástrojů SSL pro aplikace Java. Kromě potřebných tříd a rozhraní poskytuje JSSE praktický přepínač ladění příkazového řádku, který můžete použít k hodinky protokol SSL v akci. Kromě poskytnutí užitečných informací pro ladění neposlušné aplikace je hraní se sadou nástrojů skvělým způsobem, jak si promočit nohy pomocí SSL a JSSE.

Chcete-li spustit demonstraci, musíte nejprve zkompilovat následující třídu:

 public class Test {public static void main (String [] arstring) {try {new java.net.URL ("//" + arstring [0] + "/"). getContent (); } catch (Výjimka z výjimky) {exception.printStackTrace (); }}} 

Dále musíte zapnout ladění SSL a spustit výše uvedenou aplikaci. Aplikace se připojuje k zabezpečenému webu, který zadáte na příkazovém řádku, pomocí protokolu SSL přes HTTPS. První možnost načte obslužnou rutinu protokolu HTTPS. Druhá možnost, možnost ladění, způsobí, že program vytiskne své chování. Tady je příkaz (nahradit se jménem zabezpečeného webového serveru):

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

Musíte nainstalovat JSSE; pokud si nejste jisti, podívejte se na Zdroje.

Pojďme nyní na to a promluvme si o SSL a JSSE.

Krátký pohled na SSL

Kód v úvodu demonstruje nejjednodušší způsob přidání SSL do vašich aplikací - přes java.net.URL třída. Tento přístup je užitečný, ale není dostatečně flexibilní, aby vám umožnil vytvořit zabezpečenou aplikaci, která používá obecné zásuvky.

Než vám ukážu, jak tuto flexibilitu přidat, pojďme se rychle podívat na funkce SSL.

Jak název napovídá, SSL si klade za cíl poskytovat aplikacím bezpečnou sadu nástrojů podobnou soketu. V ideálním případě by mělo být snadné převést aplikaci, která používá běžné zásuvky, na aplikaci, která používá SSL.

SSL řeší tři důležité bezpečnostní problémy:

  1. Poskytuje ověřování, které pomáhá zajistit legitimitu entit zapojených do dialogu.
  2. Poskytuje soukromí. SSL pomáhá zaručit, že třetí strana nemůže dešifrovat dialog mezi dvěma entitami.
  3. Udržuje integritu. Použití MAC (ověřovací kód zprávy), který je podobný kontrolnímu součtu, pomáhá zaručit, že dialog mezi dvěma entitami nebude změněn třetí stranou.

SSL se silně spoléhá na kryptografii veřejného a tajného klíče. Využívá kryptografii tajného klíče k hromadnému šifrování dat vyměňovaných mezi dvěma aplikacemi. SSL poskytuje ideální řešení, protože algoritmy tajného klíče jsou bezpečné a rychlé. Kryptografie veřejného klíče, která je pomalejší než kryptografie tajného klíče, je lepší volbou pro ověřování a výměnu klíčů.

Referenční implementace Sun od JSSE přichází se všemi technologiemi nezbytnými k přidání SSL do vašich aplikací. Zahrnuje podporu kryptografie RSA (Rivest-Shamir-Adleman) - de facto standard pro zabezpečení na internetu. Zahrnuje implementaci SSL 3.0 - aktuálního standardu SSL - a TLS (Transport Layer Security) 1.0, další generace SSL. JSSE také poskytuje sadu API pro vytváření a používání zabezpečených soketů.

Rozhraní JSSE API

Bezpečnostní architektura Java používá Továrna designový vzor silně. Pro nezasvěcené používá návrhový vzor Factory speciální továrna objekty ke konstrukci instancí, místo aby přímo volaly jejich konstruktory. (Viz Zdroje pro klady a zápory tovární třídy.)

V JSSE všechno začíná továrnou; existuje továrna na zásuvky SSL a továrna na zásuvky serveru SSL. Vzhledem k tomu, že generické zásuvky a serverové zásuvky jsou již pro programování v síti Java zcela zásadní, předpokládám, že jste s nimi obeznámeni a rozumíte jejich rolím a rozdílům. Pokud nejste, doporučuji si vyzvednout dobrou knihu o síťovém programování v Javě.

SSLSocketFactory

Metody v javax.net.ssl.SSLSocketFactory třída spadá do tří kategorií. První se skládá z jediné statické metody, která načte výchozí továrnu soketu SSL: statická SocketFactory getDefault ().

Druhá kategorie se skládá ze čtyř metod zděděných od javax.net.SocketFactory který zrcadlí čtyři klíčové konstruktory nalezené na java.net.Socket třída a jedna metoda, která obalí existující soket soketem SSL. Každý z nich vrátí soket SSL:

  1. Socket createSocket (řetězec hostitele, int port)
  2. Socket createSocket (řetězec hostitele, int port, InetAddress clientHost, int clientPort)
  3. Socket createSocket (hostitel InetAddress, int port)
  4. Socket createSocket (hostitel InetAddress, int port, InetAddress clientHost, int clientPort)
  5. Socket createSocket (Socket socket, String host, int port, boolean autoClose)

Dvě metody ve třetí kategorii vrátí seznam šifrovacích sad SSL, které jsou ve výchozím nastavení povoleny, a úplný seznam podporovaných šifrovacích sad SSL:

  1. Řetězec [] getDefaultCipherSuites ()
  2. Řetězec [] getSupportedCipherSuites ()

Šifrovací sada je kombinací kryptografických algoritmů, které definují konkrétní úroveň zabezpečení připojení SSL. Šifrovací sada definuje, zda je připojení šifrováno, zda je ověřena integrita obsahu a jak probíhá ověřování.

SSLServerSocketFactory

Metody na javax.net.ssl.SSLServerSocketFactory třída spadá do stejných tří kategorií jako SSLSocketFactory. Nejprve existuje jediná statická metoda, která načte výchozí továrnu soketu serveru SSL: statický ServerSocketFactory getDefault ().

Metody, které vracejí zásuvky serveru SSL, zrcadlí konstruktory nalezené v java.net.ServerSocket třída:

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

Nakonec SSLServerSocketFactory obsahuje dvě metody, které vracejí seznam šifer povolených ve výchozím nastavení a seznam podporovaných šifer, v uvedeném pořadí:

  1. Řetězec [] getDefaultCipherSuites ()
  2. Řetězec [] getSupportedCipherSuites ()

Zatím je API docela jednoduché.

SSLSocket

Věci se stanou zajímavými v javax.net.ssl.SSLSocket třída. Předpokládám, že jste již obeznámeni s metodami poskytovanými jeho rodičem, Zásuvka třídy, takže se soustředím na metody, které poskytují funkčnost související s SSL.

Stejně jako dvě třídy továrny na SSL, první dvě metody uvedené níže načtou povolené a podporované šifrovací sady SSL. Třetí metoda nastavuje povolené šifrovací sady. Aplikace může použít třetí operaci k upgradu nebo downgrade rozsahu přijatelného zabezpečení, které aplikace umožní:

  1. Řetězec [] getEnabledCipherSuites ()
  2. Řetězec [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (String [] suites)

Tyto dvě metody určují, zda může soket navázat nové relace SSL, které udržují podrobnosti připojení - například sdílený tajný klíč - mezi připojeními:

  1. boolean getEnableSessionCreation ()
  2. void setEnableSessionCreation (logická vlajka)

Další dvě metody určují, zda bude soket vyžadovat ověření klienta. Metody mají smysl pouze při vyvolání na soketech režimu serveru. Nezapomeňte, že podle specifikace SSL je ověřování klienta volitelné. Například většina webových aplikací to nevyžaduje:

  1. boolean getNeedClientAuth ()
  2. void setNeedClientAuth (booleovská potřeba)

Níže uvedené metody mění soket z režimu klienta do režimu serveru. To ovlivní, kdo inicializuje handshake SSL a kdo se nejprve autentizuje:

  1. boolean getUseClientMode ()
  2. void setUseClientMode (boolean mode)

Metoda void startHandshake () vynutí handshake SSL. Je možné, ale ne běžné, vynutit novou operaci handshake v existujícím připojení.

Metoda SSLSession getSession () načte relaci SSL. Zřídka budete muset přímo přistupovat k relaci SSL.

Dvě níže uvedené metody přidávají a odebírají objekt posluchače handshake SSL. Objekt posluchače handshake je upozorněn vždy, když je na soketu dokončena operace handshake SSL.

  1. void addHandshakeCompletedListener (posluchač HandshakeCompletedListener)
  2. void removeHandshakeCompletedListener (posluchač HandshakeCompletedListener)

SSLServerSocket

The javax.net.ssl.SSLServerSocket třída je podobná javax.net.ssl.SSLSocket třída; nevyžaduje to mnoho individuální pozornosti. Ve skutečnosti je sada metod zapnutá javax.net.ssl.SSLServerSocket třída je podmnožinou metod na javax.net.ssl.SSLSocket třída.

První dvě metody uvedené níže načtou povolené a podporované šifrovací sady SSL. Třetí metoda nastavuje povolenou šifrovací sadu:

  1. Řetězec [] getEnabledCipherSuites ()
  2. Řetězec [] getSupportedCipherSuites ()
  3. void setEnabledCipherSuites (String [] suites)

Tyto dvě metody řídí, zda soket serveru může navázat nové relace SSL:

  1. boolean getEnableSessionCreation ()
  2. void setEnableSessionCreation (logická vlajka)

Následující metody určují, zda přijímané sokety budou vyžadovat ověření klienta:

  1. boolean getNeedClientAuth ()
  2. void setNeedClientAuth (logická vlajka)

Níže uvedené metody mění přijatý soket z režimu klienta do režimu serveru:

  1. boolean getUseClientMode ()
  2. void setUseClientMode (logická vlajka)

Jednoduchý příklad

Aby byl tento výukový program přehlednější, níže jsem uvedl zdrojový kód pro jednoduchý server a kompatibilního klienta. Jde o bezpečnou variantu typické aplikace ozvěny, kterou poskytuje mnoho úvodních síťových textů.

Server zobrazený níže používá JSSE k vytvoření zabezpečené zásuvky serveru. Naslouchá na soketu serveru pro připojení od zabezpečených klientů. Při spuštění serveru musíte určit úložiště klíčů, které se má použít. Úložiště klíčů obsahuje certifikát serveru. Vytvořil jsem jednoduchý úložiště klíčů, který obsahuje jeden certifikát. (Viz Zdroje ke stažení certifikátu.)

importovat java.io.InputStream; importovat java.io.InputStreamReader; import java.io.BufferedReader; import 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 = nový InputStreamReader (inputstream); BufferedReader bufferedreader = nový BufferedReader (inputstreamreader); Řetězec řetězce = null; while ((string = bufferedreader.readLine ())! = null) {System.out.println (řetězec); System.out.flush (); }} catch (Výjimka výjimky) {exception.printStackTrace (); }}} 

Ke spuštění serveru použijte následující příkaz (foobar je název souboru úložiště klíčů i jeho heslo):

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

Klient, zobrazený níže, používá JSSE k bezpečnému připojení k serveru. Při spuštění klienta musíte určit úložiště údajů o důvěryhodnosti, které se má použít a které obsahuje seznam důvěryhodných certifikátů. Vytvořil jsem jednoduchý truststore, který obsahuje jeden certifikát. (Viz Zdroje ke stažení certifikátu.)

importovat java.io.InputStream; importovat java.io.OutputStream; importovat java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.BufferedReader; importovat java.io.BufferedWriter; import java.io.IOException; import javax.net.ssl.SSLSocket; import 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 = nový InputStreamReader (inputstream); BufferedReader bufferedreader = nový BufferedReader (inputstreamreader); OutputStream outputstream = sslsocket.getOutputStream (); OutputStreamWriter outputstreamwriter = nový OutputStreamWriter (outputstream); BufferedWriter bufferedwriter = nový BufferedWriter (outputstreamwriter); Řetězec řetězce = null; while ((string = bufferedreader.readLine ())! = null) {bufferedwriter.write (string + '\ n'); bufferedwriter.flush (); }} catch (Výjimka výjimky) {exception.printStackTrace (); }}} 

Ke spuštění klienta použijte následující příkaz (foobar je název souboru úložiště údajů o důvěryhodnosti i jeho heslo):

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