Java/Network Protocol/SSL Server Socket
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
- 1 A simple single-threaded proxy server
- 2 Cipher Socket
- 3 Creating an SSL Client Socket
- 4 Creating an SSL Server Socket
- 5 implements HandshakeCompletedListener
- 6 Secure Client
- 7 Secure Communication with JSSE
- 8 Secure Login based on SSL Server Socket
- 9 Secure Server
- 10 Simple Client for secure Socket
- 11 Simple server for Secure socket
- 12 SSL Server Demo
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());
}
}