本文目录导读:

我来为您提供一个完整的Java TLS/SSL案例,包含客户端和服务端的实现。
项目结构
tls-demo/
├── src/
│ ├── server/
│ │ └── TLSServer.java
│ └── client/
│ └── TLSClient.java
└── keystore/
├── server.keystore
└── client.truststore
生成证书
首先创建证书和信任库:
# 生成服务端密钥库 keytool -genkey -alias server -keyalg RSA -keystore keystore/server.keystore \ -storepass server123 -keypass server123 -dname "CN=localhost,OU=Dev,O=Example,C=CN" # 导出服务端证书 keytool -export -alias server -keystore keystore/server.keystore \ -file keystore/server.cert -storepass server123 # 生成客户端信任库(导入服务端证书) keytool -import -alias server -file keystore/server.cert \ -keystore keystore/client.truststore -storepass client123 -noprompt
服务端实现
TLSServer.java:
package server;
import javax.net.ssl.*;
import java.io.*;
import java.security.*;
public class TLSServer {
private static final int PORT = 8443;
public static void main(String[] args) {
try {
// 加载密钥库
KeyStore keyStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream("keystore/server.keystore")) {
keyStore.load(fis, "server123".toCharArray());
}
// 创建密钥管理器
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keyStore, "server123".toCharArray());
// 创建SSL上下文
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(kmf.getKeyManagers(), null, new SecureRandom());
// 创建服务器套接字工厂
SSLServerSocketFactory ssf = sslContext.getServerSocketFactory();
// 创建SSL服务器套接字
try (SSLServerSocket serverSocket = (SSLServerSocket) ssf.createServerSocket(PORT)) {
// 设置支持的加密套件
serverSocket.setEnabledCipherSuites(serverSocket.getSupportedCipherSuites());
serverSocket.setNeedClientAuth(false); // 不需要客户端证书
System.out.println("TLS服务器启动,监听端口: " + PORT);
while (true) {
try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
System.out.println("客户端连接: " + socket.getInetAddress());
// 处理客户端请求
handleClient(socket);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void handleClient(SSLSocket socket) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()), true)) {
// 读取客户端消息
String message = reader.readLine();
System.out.println("收到客户端消息: " + message);
// 发送响应
writer.println("服务器响应: " + message.toUpperCase());
System.out.println("已发送响应");
}
}
}
客户端实现
TLSClient.java:
package client;
import javax.net.ssl.*;
import java.io.*;
import java.security.*;
public class TLSClient {
private static final String SERVER_HOST = "localhost";
private static final int SERVER_PORT = 8443;
public static void main(String[] args) {
try {
// 加载信任库
KeyStore trustStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream("keystore/client.truststore")) {
trustStore.load(fis, "client123".toCharArray());
}
// 创建信任管理器
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(trustStore);
// 创建SSL上下文
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(null, tmf.getTrustManagers(), new SecureRandom());
// 创建套接字工厂
SSLSocketFactory ssf = sslContext.getSocketFactory();
// 创建SSL套接字
try (SSLSocket socket = (SSLSocket) ssf.createSocket(SERVER_HOST, SERVER_PORT)) {
// 设置超时时间
socket.setSoTimeout(5000);
System.out.println("已连接到服务器: " + SERVER_HOST + ":" + SERVER_PORT);
// 开始TLS握手
socket.startHandshake();
// 获取SSL会话信息
SSLSession session = socket.getSession();
System.out.println("SSL会话ID: " + session.getId());
System.out.println("加密套件: " + session.getCipherSuite());
// 发送消息给服务器
sendMessage(socket, "Hello, TLS Server!");
// 读取服务器响应
receiveResponse(socket);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void sendMessage(SSLSocket socket, String message) throws IOException {
try (PrintWriter writer = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()), true)) {
writer.println(message);
System.out.println("已发送消息: " + message);
}
}
private static void receiveResponse(SSLSocket socket) throws IOException {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
String response = reader.readLine();
System.out.println("服务器响应: " + response);
}
}
}
增强版本 - 双向认证
如果需要双向认证(服务端验证客户端证书):
生成客户端证书
# 生成客户端密钥库 keytool -genkey -alias client -keyalg RSA -keystore keystore/client.keystore \ -storepass client123 -keypass client123 -dname "CN=client,OU=Dev,O=Example,C=CN" # 导出客户端证书 keytool -export -alias client -keystore keystore/client.keystore \ -file keystore/client.cert -storepass client123 # 导入客户端证书到服务端信任库 keytool -import -alias client -file keystore/client.cert \ -keystore keystore/server.truststore -storepass server123 -noprompt
修改服务端代码(增加客户端认证)
// 在服务端初始化中增加信任管理器
// 加载服务端信任库(包含客户端证书)
KeyStore serverTrustStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream("keystore/server.truststore")) {
serverTrustStore.load(fis, "server123".toCharArray());
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(serverTrustStore);
// 修改SSL上下文初始化
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
// 设置需要客户端认证
serverSocket.setNeedClientAuth(true);
修改客户端代码(提供客户端证书)
// 加载客户端密钥库
KeyStore clientKeyStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream("keystore/client.keystore")) {
clientKeyStore.load(fis, "client123".toCharArray());
}
// 创建密钥管理器
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(clientKeyStore, "client123".toCharArray());
// 修改SSL上下文初始化
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
运行测试
- 首先确保在项目根目录下有
keystore文件夹和相应的证书文件 - 编译代码:
javac server/TLSServer.java client/TLSClient.java
- 启动服务端:
java server.TLSServer
- 启动客户端:
java client.TLSClient
重要配置说明
- TLS版本选择:建议使用TLSv1.2或TLSv1.3
- 加密套件:推荐使用现代强加密套件,如TLS_AES_256_GCM_SHA384
- 证书管理:生产环境应使用正规CA签发的证书
- 性能优化:考虑使用连接池和会话复用
这个示例提供了完整的TLS通信实现,您可以根据实际需求进行适当修改。