0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

https 証明書 java21

Posted at

Eclipseを使用して、TLS 1.3をサポートし、PKCS#12形式のSSLルート証明書およびクライアント証明書を利用するJava 21のHTTPS通信を実装するには、以下の手順で2つのプロジェクトを作成します。

  1. 証明書の作成

まず、keytoolを使用して、自己署名のCA証明書、サーバー証明書、およびクライアント証明書を作成します。以下の手順で進めます。

1.自己署名のCA証明書を作成

keytool -genkeypair -alias myca -keyalg RSA -keysize 2048 -validity 3650 -dname "CN=MyCA, OU=Dev, O=MyCompany, L=City, ST=State, C=JP" -keystore myca.p12 -storetype PKCS12 -storepass capassword -keypass capassword

2.CA証明書をエクスポート
keytool -exportcert -alias myca -keystore myca.p12 -storepass capassword -rfc -file myca.crt

3.サーバーのキーストアと証明書署名要求(CSR)を作成
keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -validity 3650 -dname "CN=localhost, OU=Dev, O=MyCompany, L=City, ST=State, C=JP" -keystore server.p12 -storetype PKCS12 -storepass serverpassword -keypass serverpassword

keytool -certreq -alias server -keystore server.p12 -storepass serverpassword -file server.csr

4.CA証明書でサーバー証明書を署名

keytool -gencert -alias myca -keystore myca.p12 -storepass capassword -infile server.csr -outfile server.crt -validity 3650 -ext KU=digitalSignature,keyEncipherment -ext SAN=DNS:localhost

5.サーバーのキーストアにCA証明書と署名済みサーバー証明書をインポート
keytool -importcert -alias myca -file myca.crt -keystore server.p12 -storepass serverpassword -noprompt

keytool -importcert -alias server -file server.crt -keystore server.p12 -storepass serverpassword

6.クライアントのキーストアと証明書署名要求(CSR)を作成
keytool -genkeypair -alias client -keyalg RSA -keysize 2048 -validity 3650 -dname "CN=Client, OU=Dev, O=MyCompany, L=City, ST=State, C=JP" -keystore client.p12 -storetype PKCS12 -storepass clientpassword -keypass clientpassword

keytool -certreq -alias client -keystore client.p12 -storepass clientpassword -file client.csr

7.CA証明書でクライアント証明書を署名
keytool -gencert -alias myca -keystore myca.p12 -storepass capassword -infile client.csr -outfile client.crt -validity 3650 -ext KU=digitalSignature,keyEncipherment

8.クライアントのキーストアにCA証明書と署名済みクライアント証明書をインポート
keytool -importcert -alias myca -file myca.crt -keystore client.p12 -storepass clientpassword -noprompt

keytool -importcert -alias client -file client.crt -keystore client.p12 -storepass clientpassword

サーバー側のjava
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

public class TLSClient {
public static void main(String[] args) throws Exception {
// クライアントキーストアのパスワード
char[] clientPassphrase = "clientpassword".toCharArray();

    // クライアントキーストアの読み込み
    KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
    try (var fis = Files.newInputStream(Path.of("client.p12"))) {
        clientKeyStore.load(fis, clientPassphrase);
    }

    // キーマネージャーファクトリの初期化
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(clientKeyStore, clientPassphrase);

    // トラストストアの読み込み(サーバー証明書の検証用)
    KeyStore trustStore = KeyStore.getInstance("PKCS12");
    try (var fis = Files.newInputStream(Path.of("myca.p12"))) {
        trustStore.load(fis, "capassword".toCharArray());
    }

    // トラストマネージャーファクトリの初期化
    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
    tmf.init(trustStore);

    // SSLコンテキストの作成
    SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
    sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

    // HttpClientの作成
    HttpClient client = HttpClient.newBuilder()
            .sslContext(sslContext)
            .build();

    // HTTPリクエストの作成
    HttpRequest request = HttpRequest.newBuilder()
            .uri(new URI("https://localhost:8443"))
            .GET()
            .build();

    // リクエストの送信とレスポンスの取得
    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

    // レスポンスの表示
    System.out.println("ステータスコード: " + response.statusCode());
    System.out.println("レスポンスボディ: " + response.body());
}

}

クライアント側の実装

import javax.net.ssl.;
import java.io.
;
import java.security.KeyStore;

public class TLSServer {
public static void main(String[] args) {
try {
// キーストアとトラストストアのパスワード
char[] keystorePass = "serverpassword".toCharArray();
char[] truststorePass = "capassword".toCharArray();

        // キーストアの読み込み
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        try (FileInputStream keystoreFis = new FileInputStream("server.p12")) {
            keystore.load(keystoreFis, keystorePass);
        }

        // キーマネージャーファクトリの初期化
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(keystore, keystorePass);

        // トラストストアの読み込み
        KeyStore truststore = KeyStore.getInstance("PKCS12");
        try (FileInputStream truststoreFis = new FileInputStream("myca.p12")) {
            truststore.load(truststoreFis, truststorePass);
        }

        // トラストマネージャーファクトリの初期化
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
        tmf.init(truststore);

        // SSLコンテキストの作成
        SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        // SSLサーバーソケットの作成
        SSLServerSocketFactory ssf = sslContext.getServerSocketFactory();
        try (SSLServerSocket serverSocket = (SSLServerSocket) ssf.createServerSocket(8443)) {
            serverSocket.setNeedClientAuth(true); // クライアント認証を要求

            System.out.println("TLS 1.3 サーバーが起動しました。ポート: 8443");

            while (true) {
                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

                    String line;
                    while ((line = in.readLine()) != null && !line.isEmpty()) {
                        System.out.println("受信: " + line);
                    }

                    // レスポンスの送信
                    out.write("HTTP/1.1 200 OK\r\n");
                    out.write("Content-Type: text/plain\r\n");
                    out.write("Content-Length: 13\r\n");
                    out.write("\r\n");
                    out.write("Hello, World!");
                    out.flush();
                } catch (IOException e) {
                    System.err.println("クライアントとの通信中にエラーが発生しました: " + e.getMessage());
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?