LoginSignup
3
1

More than 1 year has passed since last update.

JavaのSSLSocketを使う(クライアント編2)

Last updated at Posted at 2021-07-22

はじめに

次はクライアント証明書を使ってみる。ついでにオレオレのサーバ証明書に対応する。

概要

サーバの時と同様に keystore, truststore をそれぞれ指定して使用する。
keystore にはクライアント証明書(秘密鍵含む)、truststore にはクライアント証明書のCA局証明書、オレオレサーバ証明書のCA局証明書を入れておく。

クライアント証明書のCA局証明書は、サーバ側のtruststoreに読み込んだものと同じ。

SSLContext

手順としては標準のtruststoreを使う場合、クライアント編1と同じく SSLContext を取得、SSLSocketFactory を得て Socket を作る。

というわけで SSLContext と SSLSocketFactory を作る部分はこのようになる。大体サーバ側と同じ。

package sslclient;

import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.net.Socket;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.io.InputStream;

public class App
{
    private static SSLContext secureSocketContext;
    private static SSLSocketFactory secureSocketFactory;

    private static void initSSL()
    {
        try (
            FileInputStream p12_file = new FileInputStream("clientcert.p12");
            FileInputStream jks_file = new FileInputStream("mytruststore.jks");
        ) {
            char[] passphrase = "passphrase".toCharArray();

            KeyStore ks = KeyStore.getInstance("pkcs12");
            ks.load(p12_file, passphrase);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
            kmf.init(ks, passphrase);

            KeyStore ts = KeyStore.getInstance("JKS");
            ts.load(jks_file, passphrase);
            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
            tmf.init(ts);

            secureSocketContext = SSLContext.getInstance("TLS");
            secureSocketContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
            secureSocketFactory = secureSocketContext.getSocketFactory();
        }
        catch (Exception e) {
            System.out.println("initSSL exception: " + e.toString());
        }
    }

clientcert.p12 がクライアント証明書のファイル名、mytruststore.jks がクライアント証明書・サーバ証明書のCA局証明書が入っているものになる。
passphrase はそのパスワード。

SSLSocket

あとはSocketを作って通信できる。以下の例では localhost:8443 に接続する。
通信するだけであれば、特にSSLSocketとして扱う必要はなく、ただのSocketで問題ない。
SSLSocketの機能を使う場合は SSLSocket にキャストして使う。

try {
    Socket sock = secureSocketFactory.createSocket("localhost", 8443);
    OutputStream os = sock.getOutputStream();
    InputStream is = sock.getInputStream();
          .
          .
          .
}
catch (Exception e) {
    System.out.println("exception: " + e.toString());
}

TLSバージョンについて

サーバの時と同様に、SSLSocketにもgetEnabledProtocols, setEnabledProtocolsがある。
Cipher Suites も同様。

3
1
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
3
1