クライアント証明書を使ったSSL通信サンプル

crtファイルと秘密鍵を渡され、Javaでクライアント証明書使ったSSL通信のサンプル作ってちょと言われたので書いた。
これでいいかは微妙…。

まず、crtファイルと秘密鍵をまとめてp12ファイルに変換。パスワードを対話で入力。

openssl pkcs12 -export -inkey private.key -in cert.crt -out cert.p12

実行時にKeyStoreに読み込ませて、HttpsURLConnectionを使ってアクセス。

package jp.co.xxxx.sample;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;

public class APIClientSample {
    static final String URL = "https://hogehoge/test.php";
    static final String P12FILE = "/path/to/cert.p12";
    static final char[] PASSWORD = "your_password".toCharArray();

    public static void main(String[] args) {
        // PKCS12ファイル読み込み
        KeyManagerFactory keyManagerFactory;
        try (FileInputStream inputStream = new FileInputStream(P12FILE)) {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(inputStream, PASSWORD);

            keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
            keyManagerFactory.init(keyStore, PASSWORD);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagerFactory.getKeyManagers(), null, null);
            
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException
                | UnrecoverableKeyException | KeyManagementException e) {
            e.printStackTrace();
        }

        // 接続
        HttpsURLConnection connection = null;
        try {
            URL url = new URL(URL);

            connection = (HttpsURLConnection) url.openConnection();
            connection.setRequestMethod("GET");

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                try (InputStreamReader isr = new InputStreamReader(connection.getInputStream(),
                        StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(isr)) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        System.out.println(line);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }
}