Java实现HTTPS案例

wen java案例 4

本文目录导读:

Java实现HTTPS案例

  1. HTTPS服务端实现
  2. HTTPS客户端实现
  3. 生成自签名证书
  4. Maven依赖
  5. 注意事项

我来为您提供一个完整的Java HTTPS实现案例,包括客户端和服务端。

HTTPS服务端实现

1 使用JDK内置HttpServer实现HTTPS服务端

import com.sun.net.httpserver.HttpsConfigurator;
import com.sun.net.httpserver.HttpsServer;
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.security.KeyStore;
public class HttpsServerExample {
    public static void main(String[] args) {
        try {
            // 创建HTTPS服务器
            HttpsServer httpsServer = HttpsServer.create(new InetSocketAddress(8443), 0);
            // 配置SSL上下文
            SSLContext sslContext = createSSLContext();
            httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext) {
                @Override
                public void configure(HttpsParameters params) {
                    try {
                        SSLContext context = getSSLContext();
                        SSLEngine engine = context.createSSLEngine();
                        params.setNeedClientAuth(false);
                        params.setCipherSuites(engine.getEnabledCipherSuites());
                        params.setProtocols(engine.getEnabledProtocols());
                        SSLParameters sslParameters = context.getSupportedSSLParameters();
                        params.setSSLParameters(sslParameters);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            });
            // 设置请求处理器
            httpsServer.createContext("/api", exchange -> {
                String response = "Hello from HTTPS Server!";
                exchange.sendResponseHeaders(200, response.getBytes().length);
                exchange.getResponseBody().write(response.getBytes());
                exchange.close();
            });
            httpsServer.start();
            System.out.println("HTTPS服务器启动在端口 8443");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static SSLContext createSSLContext() throws Exception {
        // 加载密钥库
        KeyStore keyStore = KeyStore.getInstance("JKS");
        try (FileInputStream ksStream = new FileInputStream("keystore.jks")) {
            keyStore.load(ksStream, "password".toCharArray());
        }
        // 创建密钥管理器
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, "password".toCharArray());
        // 创建SSL上下文
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
        return sslContext;
    }
}

2 使用Spring Boot实现HTTPS(可选)

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class SpringBootHttpsApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootHttpsApplication.class, args);
    }
    @GetMapping("/secure")
    public String secureEndpoint() {
        return "This is a secure HTTPS endpoint!";
    }
}

配置文件 application.properties:

server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=password
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=tomcat

HTTPS客户端实现

1 基础HTTPS客户端

import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.cert.X509Certificate;
public class HttpsClientExample {
    // 方法1:使用信任所有证书的客户端(不推荐生产环境)
    public static void basicHttpsClient() {
        try {
            // 创建信任管理器,信任所有证书
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                }
            };
            // 创建SSL上下文
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            // 禁用主机名验证
            HostnameVerifier allHostsValid = (hostname, session) -> true;
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
            // 发起HTTPS请求
            URL url = new URL("https://localhost:8443/api");
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            // 读取响应
            BufferedReader reader = new BufferedReader(
                new InputStreamReader(connection.getInputStream()));
            String line;
            StringBuilder response = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            System.out.println("响应: " + response.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2 安全的HTTPS客户端(推荐)

import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
public class SecureHttpsClient {
    public static void secureClient() {
        try {
            // 加载信任库
            KeyStore trustStore = KeyStore.getInstance("JKS");
            try (FileInputStream tsStream = new FileInputStream("truststore.jks")) {
                trustStore.load(tsStream, "changeit".toCharArray());
            }
            // 创建信任管理器
            TrustManagerFactory trustManagerFactory = 
                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);
            // 创建SSL上下文
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
            // 设置默认SSL配置
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
            // 设置主机名验证(建议使用默认验证)
            HttpsURLConnection.setDefaultHostnameVerifier(
                HttpsURLConnection.getDefaultHostnameVerifier());
            // 发起请求
            URL url = new URL("https://example.com/api");
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            if (connection.getResponseCode() == 200) {
                BufferedReader reader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
                String line;
                StringBuilder response = new StringBuilder();
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                reader.close();
                System.out.println("响应: " + response.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3 使用Apache HttpClient实现HTTPS

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
public class ApacheHttpsClient {
    public static void useApacheHttpClient() {
        try {
            // 使用系统默认SSL上下文
            SSLContext sslContext = SSLContexts.createSystemDefault();
            // 创建SSL连接工厂
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                new String[]{"TLSv1.2", "TLSv1.3"},
                null,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            // 创建HTTP客户端
            CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
            // 创建GET请求
            HttpGet request = new HttpGet("https://api.example.com/data");
            request.addHeader("Accept", "application/json");
            // 执行请求
            CloseableHttpResponse response = httpClient.execute(request);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    String result = EntityUtils.toString(entity);
                    System.out.println("响应: " + result);
                }
            } finally {
                response.close();
            }
            httpClient.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4 使用Java 11+ HttpClient

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class Java11HttpsClient {
    public static void useJava11Client() {
        try {
            // 创建HTTPS客户端
            HttpClient httpClient = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_2)
                .connectTimeout(Duration.ofSeconds(10))
                .build();
            // 创建请求
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://api.example.com/data"))
                .timeout(Duration.ofSeconds(30))
                .header("Accept", "application/json")
                .GET()
                .build();
            // 发送请求并获取响应
            HttpResponse<String> response = httpClient.send(
                request, 
                HttpResponse.BodyHandlers.ofString());
            System.out.println("状态码: " + response.statusCode());
            System.out.println("响应: " + response.body());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

生成自签名证书

# 生成PKCS12格式的密钥库
keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 \
  -storetype PKCS12 -keystore keystore.p12 -validity 3650 \
  -storepass password -dname "CN=localhost, OU=Dev, O=MyOrg, L=City, S=State, C=CN"
# 生成JKS格式的密钥库
keytool -genkeypair -alias server -keyalg RSA -keysize 2048 \
  -keystore keystore.jks -validity 3650 \
  -storepass password -keypass password \
  -dname "CN=localhost, OU=Dev, O=MyOrg, L=City, S=State, C=CN"
# 导出证书
keytool -export -alias server -keystore keystore.jks \
  -storepass password -file server.crt
# 创建信任库
keytool -import -alias server -file server.crt \
  -keystore truststore.jks -storepass changeit -noprompt

Maven依赖

<dependencies>
    <!-- Apache HttpClient -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    <!-- Spring Boot (可选) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.6.3</version>
    </dependency>
</dependencies>

注意事项

  1. 生产环境:不要使用信任所有证书的客户端,应使用正式的证书或正确的信任库
  2. 证书管理:定期更新和轮换证书
  3. 安全配置:使用最新的TLS协议版本(TLSv1.2或TLSv1.3)
  4. 性能优化:考虑使用连接池管理连接
  5. 错误处理:正确捕获和处理SSL握手异常

这个案例涵盖了Java HTTPS实现的主要方面,包括服务端和客户端的完整实现。

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