public class Server { int port = portNumber; SSLServerSocket server; try { SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); server = (SSLServerSocket) factory.createServerSocket(portNumber); SSLSocket client = (SSLSocket) server.accept();
// Create input and output streams as usual // send secure messages to client through the // output stream // receive secure messages from client through // the input stream } catch(Exception e) { } } 为了使客户端变得安全,下面的例子中加黑显示的内容是必须的:
public class Client { ... try { SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); server = (SSLServerSocket) factory.createServerSocket(portNumber); SSLSocket client = (SSLSOcket) factory.createSocket(serverHost, port);
// Create input and output streams as usual // send secure messages to server through the // output stream receive secure // messages from server through the input stream } catch(Exception e) { } }
/** * This class implements a multithreaded simple HTTP * server that supports the GET request method. * It listens on port 44, waits client requests, and * serves documents. */
public class HttpServer { // The port number which the server // will be listening on public static final int HTTP_PORT = 8080;
public ServerSocket getServer() throws Exception { return new ServerSocket(HTTP_PORT); }
// multi-threading -- create a new connection // for each request public void run() { ServerSocket listen; try { listen = getServer(); while(true) { Socket client = listen.accept(); ProcessConnection cc = new ProcessConnection(client); } } catch(Exception e) { System.out.println("Exception: "+e.getMessage()); } }
// main program public static void main(String argv[]) throws Exception { HttpServer httpserver = new HttpServer(); httpserver.run(); } }
class ProcessConnection extends Thread { Socket client; BufferedReader is;
DataOutputStream os;
public ProcessConnection(Socket s) { // constructor client = s; try { is = new BufferedReader(new InputStreamReader (client.getInputStream())); os = new DataOutputStream(client.getOutputStream()); } catch (IOException e) { System.out.println("Exception: "+e.getMessage()); } this.start(); // Thread starts here...this start() will call run() }
public void run() { try { // get a request and parse it. String request = is.readLine(); System.out.println( "Request: "+request ); StringTokenizer st = new StringTokenizer( request ); if ( (st.countTokens() >= 2) && st.nextToken().equals("GET") ) { if ( (request = st.nextToken()).startsWith("/") ) request = request.substring( 1 ); if ( request.equals("") ) request = request + "index.html"; File f = new File(request); shipDocument(os, f); } else { os.writeBytes( "400 Bad Request" ); } client.close(); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } }
/** * Read the requested file and ships it * to the browser if found. */ public static void shipDocument(DataOutputStream out, File f) throws Exception { try { DataInputStream in = new DataInputStream(new FileInputStream(f)); int len = (int) f.length(); byte[] buf = new byte[len]; in.readFully(buf); in.close(); out.writeBytes("HTTP/1.0 200 OK "); out.writeBytes("Content-Length: " + f.length() +" "); out.writeBytes("Content-Type: text/html
Enter keystore password: hellothere What is your first and last name? [Unknown]: ultra.domain.com What is the name of your organizational unit? [Unknown]: Training and Consulting What is the name of your organization? [Unknown]: Javacourses.com What is the name of your City or Locality? [Unknown]: Toronto What is the name of your State or Province? [Unknown]: Ontario What is the two-letter country code for this unit? [Unknown]: CA Is CN=ultra, OU=Training and Consulting, O=Javacourses.com, L=Toronto, ST=Ontario, C=CA correct? [no]: yes
Enter key password for (RETURN if same as keystore password): hiagain 正如你所看到的,keytool 提示为 keystore 输入密码,那是因为让服务器能访问 keystore 就必须让它知道密码。那工具也要求为别名输入一个密码。如果你愿意,这些密码信息能由 keytool 从命令行指定,使用参数 -storepass 和 -keypass 就行了。注意我使用了“ultra.domain.com”作为姓名,这个名字是为我的机器假想的一个名字。你应该输入服务器的主机名或者 IP 地址。
/** * This class implements a multithreaded simple HTTPS * server that supports the GET request method. * It listens on port 44, waits client requests * and serves documents. */
如果你接受证书,你就可以看到安全连接之后的页面。以后访问同一个网站的时候浏览器就不再会弹出安全警告了。注意有许多网站使用 HTTPS,而证书是自己产生或者由不知名的 CA 产生的。例如,https://www.jam.ca。如果你没访问过这个网页,你会看到一个像图 3 一样的安全警告。
-------------------------------------------------------------------------------- 注意:你接受证书以后,它只对当前的会话有效,也就是说,如果你完全退出浏览器后,它就失效了。Netscape 和 Microsoft Internet Explorer (MSIE) 都允许你永久保证证书。在 MSIE 中的作法是:选择图 3 所示的“View Certificate”并在新开的窗口中选择“Install Certificate”。