安全


安全是一个复杂的话题。在本节中,我们将演示该主题的几个简单方面,因为它与网络有关。具体来说,我们将创建一个安全的回显服务器。创建安全回显服务器与我们之前开发的非安全回显服务器没有太大区别。然而,在幕后有很多事情要让它发挥作用。我们可以忽略许多这些细节现在,但我们会更深入地钻研它在第8章网络安全

我们将使用该类来实例化安全服务器套接字。此外,有必要创建底层 SSL 机制可用于加密通信的密钥。 SSLServerSocketFactory


创建 SSL 服务器



SSLServerSocket在以下示例中声明了一个类作为回显服务器。由于它与前面的回显服务器类似,我们将不解释它的实现,除了它与SSLServerSocketFactory类的使用的关系。其静态getDefault方法返回 的实例ServerSocketFactory。它的createServerSocket方法返回一个ServerSocket绑定到8000能够支持安全通信的端口的实例。否则,它的组织和功能类似于以前的回显服务器:



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.ssl.SSLServerSocketFactory;

public class SSLServerSocket {
	public static void main(String[] args) {
		try {
			SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
			ServerSocket serverSocket = ssf.createServerSocket(8000);
			System.out.println("SSLServerSocket Started");
			try (Socket socket = serverSocket.accept();
					PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
					BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
				System.out.println("Client socket created");
				String line = null;
				while (((line = br.readLine()) != null)) {
					System.out.println(line);
					out.println(line);
				}
				br.close();
				System.out.println("SSLServerSocket Terminated");
			} catch (IOException ex) {
// Handle exceptions
			}
		} catch (IOException ex) {
// Handle exceptions
		}
	}
}


创建 SSL 客户端



安全回显客户端也类似于之前的非安全回显客户端。在SSLSocketFactorygetDefault返回一个SSLSocketFactory实例,其createSocket创建一个连接到安全的回声服务器的套接字。申请如下:



import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

import javax.net.ssl.SSLSocketFactory;

public class SSLClientSocket {
	public static void main(String[] args) throws Exception {
		System.out.println("SSLClientSocket Started");
		SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
		try (Socket socket = sf.createSocket("localhost", 8000);
				PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
				BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
			Scanner scanner = new Scanner(System.in);
			while (true) {
				System.out.print("Enter text: ");
				String inputLine = scanner.nextLine();
				if ("quit".equalsIgnoreCase(inputLine)) {
					break;
				}
				out.println(inputLine);
				System.out.println("Server response: " + br.readLine());
			}
			System.out.println("SSLServerSocket Terminated");
		}
	}
}



如果我们在客户端之后执行此服务器,它们将因连接错误而中止。这是因为我们没有提供一组应用程序可以共享和用于保护它们之间传递的数据的密钥。


生成安全密钥



为了提供必要的密钥,我们需要创建一个密钥库来保存密钥。当应用程序执行时,密钥库必须可供应用程序使用。首先,我们将演示如何创建密钥库,然后我们将向您展示必须提供哪些运行时参数。

在 Java SE SDK 的bin目录中有一个名为keytool. 这是一个命令级程序,它将生成必要的密钥并将它们存储在密钥文件中。在 Windows 中,您需要打开一个命令窗口并导航到源文件的根目录。此目录将包含保存应用程序包的目录。



注意

在 Mac 上,您可能在生成密钥对时遇到问题。有关在 Mac 上使用此工具的更多信息,访问https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/keytool.1.html



您还需要bin使用类似于以下命令的命令设置目录的路径。需要此命令来查找和执行keytool应用程序:



set path= C:\Program Files\Java\jdk1.8.0_25\bin;%path%



接下来,输入keytool命令。系统将提示您输入用于创建密钥的密码和其他信息。此处显示了此过程,其中使用了密码,123456但在输入时未显示:



keytool -genkey -keyalg RSA -keystore C:\keystore.jks
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
  [Unknown]:
您的组织单位名称是什么?
  [Unknown]:
您的组织名称是什么?
  [Unknown]:
您所在的城市或区域名称是什么?
  [Unknown]:
您所在的省/市/自治区名称是什么?
  [Unknown]:
该单位的双字母国家/地区代码是什么?
  [Unknown]:
CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown是否正确?
  [否]:  y



创建密钥库后,您可以运行服务器和客户端应用程序。这些应用程序的启动方式取决于您的项目是如何创建的。您可以从 IDE 执行它,或者您可能需要从命令窗口启动它们。

接下来是可以从命令窗口使用的命令。该java命令的两个参数是密钥库的位置和密码。它们需要从包目录的根目录执行:



java -Djavax.net.ssl.keyStore=keystore.jks -Djavax.net.ssl.keyStorePassword=123456 SSLServerSocket
java -Djavax.net.ssl.trustStore=keystore.jks -Djavax.net.ssl.trustStorePassword=123456 SSLClientSocket



如果要使用 IDE,请使用运行时命令参数的等效设置。下面的例子说明了客户端和服务器之间的一种可能的交换。服务器窗口的输出首先显示,然后是客户端的输出:

SSLServerSocket Started

Client socket created

Hello echo server

Safe and secure

SSLServerSocket Terminated

SSLClientSocket Started

Enter text: Hello echo server

Server response: Hello echo server

Enter text: Safe and secure

Server response: Safe and secure

Enter text: quit

SSLServerSocket Terminated

SSLServerSocket 终止

除了此处显示的内容之外,还有更多关于 SSL 的信息需要了解。然而,这提供了过程的概述,在呈现更细节第8章网络安全