Java/Network Protocol/SSL Server Socket

Материал из Java эксперт
Перейти к: навигация, поиск

A simple single-threaded proxy server

  
/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
//package je3.net;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * This class implements a simple single-threaded proxy server.
 */
public class SimpleProxyServer {
  /** The main method parses arguments and passes them to runServer */
  public static void main(String[] args) throws IOException {
    try {
      // Check the number of arguments
      if (args.length != 3)
        throw new IllegalArgumentException("Wrong number of args.");
      // Get the command-line arguments: the host and port we are proxy
      // for and the local port that we listen for connections on.
      String host = args[0];
      int remoteport = Integer.parseInt(args[1]);
      int localport = Integer.parseInt(args[2]);
      // Print a start-up message
      System.out.println("Starting proxy for " + host + ":" + remoteport + " on port " + localport);
      // And start running the server
      runServer(host, remoteport, localport); // never returns
    } catch (Exception e) {
      System.err.println(e);
      System.err.println("Usage: java SimpleProxyServer " + "<host> <remoteport> <localport>");
    }
  }
  /**
   * This method runs a single-threaded proxy server for host:remoteport on the
   * specified local port. It never returns.
   */
  public static void runServer(String host, int remoteport, int localport) throws IOException {
    // Create a ServerSocket to listen for connections with
    ServerSocket ss = new ServerSocket(localport);
    // Create buffers for client-to-server and server-to-client transfer.
    // We make one final so it can be used in an anonymous class below.
    // Note the assumptions about the volume of traffic in each direction.
    final byte[] request = new byte[1024];
    byte[] reply = new byte[4096];
    // This is a server that never returns, so enter an infinite loop.
    while (true) {
      // Variables to hold the sockets to the client and to the server.
      Socket client = null, server = null;
      try {
        // Wait for a connection on the local port
        client = ss.accept();
        // Get client streams. Make them final so they can
        // be used in the anonymous thread below.
        final InputStream from_client = client.getInputStream();
        final OutputStream to_client = client.getOutputStream();
        // Make a connection to the real server.
        // If we cannot connect to the server, send an error to the
        // client, disconnect, and continue waiting for connections.
        try {
          server = new Socket(host, remoteport);
        } catch (IOException e) {
          PrintWriter out = new PrintWriter(to_client);
          out.print("Proxy server cannot connect to " + host + ":" + remoteport + ":\n" + e + "\n");
          out.flush();
          client.close();
          continue;
        }
        // Get server streams.
        final InputStream from_server = server.getInputStream();
        final OutputStream to_server = server.getOutputStream();
        // Make a thread to read the client"s requests and pass them
        // to the server. We have to use a separate thread because
        // requests and responses may be asynchronous.
        Thread t = new Thread() {
          public void run() {
            int bytes_read;
            try {
              while ((bytes_read = from_client.read(request)) != -1) {
                to_server.write(request, 0, bytes_read);
                to_server.flush();
              }
            } catch (IOException e) {
            }
            // the client closed the connection to us, so close our
            // connection to the server. This will also cause the
            // server-to-client loop in the main thread exit.
            try {
              to_server.close();
            } catch (IOException e) {
            }
          }
        };
        // Start the client-to-server request thread running
        t.start();
        // Meanwhile, in the main thread, read the server"s responses
        // and pass them back to the client. This will be done in
        // parallel with the client-to-server request thread above.
        int bytes_read;
        try {
          while ((bytes_read = from_server.read(reply)) != -1) {
            to_client.write(reply, 0, bytes_read);
            to_client.flush();
          }
        } catch (IOException e) {
        }
        // The server closed its connection to us, so we close our
        // connection to our client.
        // This will make the other thread exit.
        to_client.close();
      } catch (IOException e) {
        System.err.println(e);
      } finally { // Close the sockets no matter what happens.
        try {
          if (server != null)
            server.close();
          if (client != null)
            client.close();
        } catch (IOException e) {
        }
      }
    }
  }
}





Cipher Socket

 
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.SecretKey;
/**
 *
 * @author  Scott.Stark@jboss.org
 */
public class CipherSocket extends Socket
{
   private Cipher cipher;
   private Socket delegate;
   String algorithm;
   SecretKey key;
   /** Creates a new instance of CipherSocket */
   public CipherSocket(String host, int port, String algorithm, SecretKey key)
      throws IOException
   {
      super(host, port);
      this.algorithm = algorithm;
      this.key = key;
   }
   public CipherSocket(Socket delegate, String algorithm, SecretKey key)
      throws IOException
   {
      this.delegate = delegate;
      this.algorithm = algorithm;
      this.key = key;
   }
   public InputStream getInputStream() throws IOException
   {
      InputStream is = delegate == null ? super.getInputStream() : delegate.getInputStream();
      Cipher cipher = null;
      try
      {
         cipher = Cipher.getInstance(algorithm);
         int size = cipher.getBlockSize();
         byte[] tmp = new byte[size];
         Arrays.fill(tmp, (byte)15);
         IvParameterSpec iv = new IvParameterSpec(tmp);
         cipher.init(Cipher.DECRYPT_MODE, key, iv);
      }
      catch(Exception e)
      {
         e.printStackTrace();
         throw new IOException("Failed to init cipher: "+e.getMessage());
      }
      CipherInputStream cis = new CipherInputStream(is, cipher);
      return cis;
   }
   public OutputStream getOutputStream() throws IOException
   {
      OutputStream os = delegate == null ? super.getOutputStream() : delegate.getOutputStream();
      Cipher cipher = null;
      try
      {
         cipher = Cipher.getInstance(algorithm);
         int size = cipher.getBlockSize();
         byte[] tmp = new byte[size];
         Arrays.fill(tmp, (byte)15);
         IvParameterSpec iv = new IvParameterSpec(tmp);
         cipher.init(Cipher.ENCRYPT_MODE, key, iv);
      }
      catch(Exception e)
      {
         throw new IOException("Failed to init cipher: "+e.getMessage());
      }
      CipherOutputStream cos = new CipherOutputStream(os, cipher);
      return cos;
   }
}





Creating an SSL Client Socket

  
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
public class Main {
  public static void main(String[] argv) throws Exception {
    int port = 443;
    String hostname = "hostname";
    SocketFactory socketFactory = SSLSocketFactory.getDefault();
    Socket socket = socketFactory.createSocket(hostname, port);

    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();
    // Read from in and write to out...
    in.close();
    out.close();
  }
}





Creating an SSL Server Socket

  
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocketFactory;
public class Main {
  public static void main(String[] argv) throws Exception {
    int port = 443;
    ServerSocketFactory ssocketFactory = SSLServerSocketFactory.getDefault();
    ServerSocket ssocket = ssocketFactory.createServerSocket(port);
    Socket socket = ssocket.accept();
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();
    // Read from in and write to out...
    in.close();
    out.close();
  }
}





implements HandshakeCompletedListener

  
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
class MyHandshakeListener implements HandshakeCompletedListener {
  public void handshakeCompleted(HandshakeCompletedEvent e) {
    System.out.println("Using cipher suite: " + e.getCipherSuite());
  }
}
public class Main {
  public static void main(String[] args) throws Exception {
    SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
    SSLSocket socket = (SSLSocket) factory.createSocket("127.0.0.1", 8080);
    String[] suites = socket.getSupportedCipherSuites();
    socket.setEnabledCipherSuites(suites);
    socket.addHandshakeCompletedListener(new MyHandshakeListener());
    socket.startHandshake();
    System.out.println("Just connected to " + socket.getRemoteSocketAddress());
  }
}





Secure Client

   
import java.net.*;
import java.io.*;
import javax.net.*;
import java.security.*;
import javax.net.ssl.*;
import javax.crypto.*;
public class SecureClient {
   public static final int PORT = 10000;
   public static void main(String[] args) throws Exception {
      String host = "127.0.0.1";
      SocketFactory sf = SSLSocketFactory.getDefault();
      SSLSocket sock = (SSLSocket) sf.createSocket(host, PORT);
      System.out.println("Server connected");
      InputStream rawIn = sock.getInputStream( );
      BufferedReader in = new BufferedReader(new InputStreamReader(rawIn));
      System.out.println(in.readLine( ));
      sock.close() ;
   }
}





Secure Communication with JSSE

  
 
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
public class Main {
  public static void main(String args[]) throws Exception {
    SocketFactory factory = SSLSocketFactory.getDefault();
    Socket socket = factory.createSocket("127.0.0.1", 8080);
    OutputStream outputStream = socket.getOutputStream();
    PrintWriter out = new PrintWriter(outputStream);
    out.print("GET / HTTP/1.0\r\n\r\n");
    out.flush();
    InputStream inputStream = socket.getInputStream();
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader in = new BufferedReader(inputStreamReader);
    String line;
    while ((line = in.readLine()) != null) {
      System.out.println(line);
    }
    out.close();
    in.close();
    socket.close();
  }
}





Secure Login based on SSL Server Socket

  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
class LoginClient {
  public LoginClient() {
    try {
      SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
      SSLSocket socket = (SSLSocket) socketFactory.createSocket("localhost", 7070);
      PrintWriter output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
      String userName = "MyName";
      output.println(userName);
      String password = "MyPass";
      output.println(password);
      output.flush();
      BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      String response = input.readLine();
      System.out.println(response);
      output.close();
      input.close();
      socket.close();
    } catch (IOException ioException) {
      ioException.printStackTrace();
    } finally {
      System.exit(0);
    }
  }
  public static void main(String args[]) {
    new LoginClient();
  }
}
//////////////////////////////////////////////////////////////////////////////////////////////
class LoginServer {
  private static final String CORRECT_USER_NAME = "Java";
  private static final String CORRECT_PASSWORD = "HowToProgram";
  private SSLServerSocket serverSocket;
  public LoginServer() throws Exception {
    SSLServerSocketFactory socketFactory = (SSLServerSocketFactory) SSLServerSocketFactory
        .getDefault();
    serverSocket = (SSLServerSocket) socketFactory.createServerSocket(7070);
  }
  private void runServer() {
    while (true) {
      try {
        System.err.println("Waiting for connection...");
        SSLSocket socket = (SSLSocket) serverSocket.accept();
        BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        PrintWriter output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
        String userName = input.readLine();
        String password = input.readLine();
        if (userName.equals(CORRECT_USER_NAME) && password.equals(CORRECT_PASSWORD)) {
          output.println("Welcome, " + userName);
        } else {
          output.println("Login Failed.");
        }
        output.close();
        input.close();
        socket.close();
      } catch (IOException ioException) {
        ioException.printStackTrace();
      }
    }
  }
  public static void main(String args[]) throws Exception {
    LoginServer server = new LoginServer();
    server.runServer();
  }
}





Secure Server

   
import java.net.*;
import java.io.*;
import javax.net.*;
import java.security.*;
import javax.net.ssl.*;
import javax.crypto.*;
public class SecureServer {
  public static void main(String[] args) throws Exception {
         ServerSocketFactory ssf = SSLServerSocketFactory.getDefault();
         SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(98999);
         Socket sock = ss.accept();
         ss.close();
         OutputStream rawOut = sock.getOutputStream();
         PrintWriter out = new PrintWriter(new OutputStreamWriter(rawOut));
         out.println(new java.util.Date().toString());
         out.flush();
         sock.close();
  }
}





Simple Client for secure Socket

  
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
public class SSLSimpleClient {
  public static void main(String[] args) throws Exception {
    SocketFactory sf = SSLSocketFactory.getDefault();
    Socket s = sf.createSocket(args[0], Integer.parseInt(args[1]));
    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    PrintWriter pw = new PrintWriter(s.getOutputStream());
    pw.println("from jexp.");
    pw.flush();
    System.out.println(br.readLine());
    s.close();
  }
}





Simple server for Secure socket

  
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLServerSocketFactory;
public class SSLSimpleServer extends Thread {
  public static void main(String[] args) throws Exception {
    ServerSocketFactory ssf = SSLServerSocketFactory.getDefault();
    ServerSocket ss = ssf.createServerSocket(9096);
    System.out.println("Ready...");
    while (true) {
      new SSLSimpleServer(ss.accept()).start();
    }
  }
  private Socket sock;
  public SSLSimpleServer(Socket s) {
    sock = s;
  }
  public void run() {
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
      PrintWriter pw = new PrintWriter(sock.getOutputStream());
      String data = br.readLine();
      pw.println(data);
      pw.close();
      sock.close();
    } catch (IOException ioe) {
      // Client disconnected
    }
  }
}





SSL Server Demo

  
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
public class Main {
  public static void main(String[] argv) throws Exception {
    SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
    SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(8080);
    String[] suites = serverSocket.getSupportedCipherSuites();
    for (int i = 0; i < suites.length; i++) {
      System.out.println(suites[i]);
    }
    serverSocket.setEnabledCipherSuites(suites);
    String[] protocols = serverSocket.getSupportedProtocols();
    for (int i = 0; i < protocols.length; i++) {
      System.out.println(protocols[i]);
    }
    SSLSocket socket = (SSLSocket) serverSocket.accept();
    socket.startHandshake();
    System.out.println(socket.getRemoteSocketAddress());
  }
}