Java TLS案例

wen java案例 2

本文目录导读:

Java TLS案例

  1. 项目结构
  2. 生成证书
  3. 服务端实现
  4. 客户端实现
  5. 增强版本 - 双向认证
  6. 运行测试
  7. 重要配置说明

我来为您提供一个完整的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());

运行测试

  1. 首先确保在项目根目录下有keystore文件夹和相应的证书文件
  2. 编译代码:
    javac server/TLSServer.java client/TLSClient.java
  3. 启动服务端:
    java server.TLSServer
  4. 启动客户端:
    java client.TLSClient

重要配置说明

  • TLS版本选择:建议使用TLSv1.2或TLSv1.3
  • 加密套件:推荐使用现代强加密套件,如TLS_AES_256_GCM_SHA384
  • 证书管理:生产环境应使用正规CA签发的证书
  • 性能优化:考虑使用连接池和会话复用

这个示例提供了完整的TLS通信实现,您可以根据实际需求进行适当修改。

上一篇mTLS案例

下一篇Java HSTS案例

抱歉,评论功能暂时关闭!