JavaにおけるSSLの紹介

JavaでのSSLの概要

1. 概要

このチュートリアルでは、SSLを紹介し、JSSE(Java Secure Socket Extension)APIを使用してJavaでSSLを使用する方法を探ります。

2. 前書き

簡単に言えば、Secured Socket Layer (SSL) enables a secured connection between two parties、通常はクライアントとサーバーです。

SSLは、ネットワーク接続で動作する2つのデバイス間に安全なチャネルをプロビジョニングします。 SSLの一般的な例の1つは、WebブラウザーとWebサーバー間の安全な通信を有効にすることです。

この特定のケースでは、WebブラウザーはHTTPS(Securedの略)接続を使用して、個別のWebサーバーによって提供されるリソースにアクセスします。

SSLは、次の3つの主要な情報セキュリティ原則をサポートするために必要です。

  • Encryption:当事者間のデータ送信を保護します

  • Authentication:接続するサーバーが実際に適切なサーバーであることを確認します。

  • Data integrity:要求されたデータが効果的に配信されるものであることを保証します。

Javaは、暗号化形式でメッセージを送受信するために、開発者がクライアントとの安全な接続を確立するのに役立ついくつかのセキュリティベースのAPIを提供します。

  • Java Secured-Socket Extension(JSSE)

  • Java暗号化アーキテクチャ(JCA)

  • Java Cryptographic Extension(JCE)

次のセクションでは、Javaが安全な通信を有効にするために使用するSecure SocketExtensionを紹介します。

3. JSSE API

JavaセキュリティAPIは、Factoryのデザインパターンを広範囲に利用します。

実際、JSSEのファクトリを使用してすべてがインスタンス化されます。

3.1. SSLSocketFactory

javax.net.ssl.SSLSocketFactoryは、SSLSocketオブジェクトの作成に使用されます。

このクラスには、APIの3つのグループが含まれます。

最初のグループは、デフォルトのインスタンスを取得するために使用される単一の静的getDefault()メソッドで構成され、これにより、 SSLSocketインスタンスを作成できます。

2番目のグループは、SSLSocketインスタンスの作成に使用できる5つのメソッドで構成されています。

  • ソケットcreateSocket(文字列ホスト、intポート)

  • ソケットcreateSocket(文字列ホスト、intポート、InetAddress clientHost、int clientPort)

  • ソケットcreateSocket(InetAddressホスト、intポート)

  • ソケットcreateSocket(InetAddressホスト、intポート、InetAddress clientHost、int clientPort)

  • ソケットcreateSocket(ソケットソケット、文字列ホスト、intポート、ブール値autoClose)

このクラスを直接使用するには、デフォルトインスタンスを取得するか、SSLSocketFactoryインスタンスを取得するメソッドを含むjavax.net.ssl.SSLContextオブジェクトを使用します。

3.2. SSLSocket

このクラスはSocketクラスを拡張し、安全なソケットを提供します。 このようなソケットは通常のストリームソケットです。

さらに、基盤となるネットワーク転送プロトコル上にセキュリティ保護の層を追加します。

SSLSocketインスタンスは、指定されたポートで指定されたホストへのSSL接続を構築します。

これにより、接続のクライアント側を特定のアドレスとポートにバインドできます。

3.3. SSLServerSocketFactory

SSLServerSocketFactoryクラスはSSLSocketFactoryと非常に似ていますが、SSLSocketインスタンスの代わりにSSLServerSocketインスタンスを作成する点が異なります。

類似性により、メソッドはSSLSocketFactoryクラスと同様にcreateServerSocketと呼ばれます。

3.4. SSLServerSocket

SSLServerSocketクラスは、SSLSocketクラスに類似しています。 SSLServerSocketクラスのメソッドは、SSLSocketクラスメソッドのサブセットです。 SSL接続の反対側で動作します

4. SSLの例

サーバーへの安全な接続を作成する方法の例を示しましょう。

String host = getHost(...);
Integer port = getPort(...);
SSLSocketFactory sslsocketfactory = SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory
  .createSocket(host, port);
InputStream in = sslsocket.getInputStream();
OutputStream out = sslsocket.getOutputStream();

out.write(1);
while (in.available() > 0) {
    System.out.print(in.read());
}

System.out.println("Secured connection performed successfully");

エラー“javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target while establishing the SSL connection”it indicates that we don’t have the public certificate of the server which we’re trying to connect in the Java truststore.が発生した場合

トラストストアは、Javaが保護された接続を検証するために使用する信頼できる証明書を含むファイルです。

この問題を解決するために、いくつかのオプションがあります。

  • サーバーの公開証明書を、Javaで使用されるデフォルトのcacerts truststoreに追加します。 SSL接続の開始中

  • トラストストアファイルを指すようにjavax.net.ssl.trustStore environment変数を設定して、接続先のサーバーの公開証明書を含むファイルをアプリケーションが取得できるようにします。

Javaのデフォルトのトラストストアに新しい証明書をインストールする手順は次のとおりです。

  1. サーバーから証明書を抽出します:openssl s_client -connect server:443

  2. keytoolを使用して証明書をトラストストアにインポートします:keytool -import -alias alias.server.com -keystore $JAVA_HOME/jre/lib/security/cacerts

これを実行すると、例を再度実行してSecured connection performed successfullyメッセージを取得できるようになります。

5. 結論

この記事では、SSLとJava用のSSLを実装するJSSE APIを紹介しました。 SSLとJSSEを使用することにより、Javaアプリケーションと、アプリケーション間およびアプリケーション内の通信をより安全にすることができます。

いつものように、この記事で紹介されているコードはover on Githubで利用できます。