【Java】 自前認証局(オレオレ証明書) のSSLサーバに接続するには...

サンプル

SampleSSLConnectHelper.java

import java.security.cert.CertificateException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SampleSSLConnectHelper {
   /**
    * 自前認証局(オレオレ証明書) のSSLサーバに接続する前に呼び出す
    */
   public static void initialize() {
      try {
         // SSLContextの作成
         SSLContext sslContext = SSLContext.getInstance("TLS");
         // SSLContextの初期化
         sslContext.init(null,
               SampleSSLConnectHelper.getTrustManagersToAllowAllCert(), null);
         SSLContext.setDefault(sslContext);
         // HTTPSで使用する SSLソケットの作成(SSLSocketFactory) をセット
         HttpsURLConnection.setDefaultSSLSocketFactory(
               sslContext.getSocketFactory());

         // HostnameVerifier を作成
         HostnameVerifier hostnameVerifier = 
               SampleSSLConnectHelper.getHostnameVerifierToAllowAllHost();

         // HTTPSで使用する ホスト名の検証(HostnameVerifier) をセット
         // デフォルトの検証が失敗した場合(証明書の氏名[CN]が異なる場合など)に呼び出される
         HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
      } catch (Exception ex) {
         throw new RuntimeException(ex);
      }
   }

   /**
    * すべての証明書を受け付けるTrustManagerを返す
    *
    * @return TrustManager[]
    */
   private static TrustManager[] getTrustManagersToAllowAllCert() {
      TrustManager[] transManagers = { new X509TrustManager() {
         /**
          * ピアから提出された一部のまたは完全な証明書チェーンを使用して、
          * 信頼できるルートへの証明書パスを構築し、認証タイプに基づいて
          * クライアント認証を検証できるかどうか、信頼できるかどうかを返す。
          */
         @Override
         public void checkClientTrusted(
               java.security.cert.X509Certificate[] chains, String authType)
               throws CertificateException {
            // do nothing
         }

         /**
          * ピアから提出された一部のまたは完全な証明書チェーンを使用して、
          * 信頼できるルートへの証明書パスを構築し、認証タイプに基づいて
          * サーバ認証を検証できるかどうか、また信頼できるかどうかを返す。
          */
         @Override
         public void checkServerTrusted(
               java.security.cert.X509Certificate[] chains, String authType)
               throws CertificateException {
            // do nothing
         }
         /**
          * 認証するピアについて信頼されている、証明書発行局の証明書の配列を返す
          */
         @Override
         public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            // do nothing
            return null;
         }
      } };
      return transManagers;
   }

   /**
    * すべてのホストを信用するHostnameVerifierを返す。
    *
    * @return HostnameVerifier
    */
   private static HostnameVerifier getHostnameVerifierToAllowAllHost() {
      return new HostnameVerifier() {
         /**
          * 証明書のURLと一致しない場合に飛んでくる
          */
         @Override
         public boolean verify(String hostname, SSLSession session) {
            // すべてのホストを信用
            return true;
         }
      };
   }
}

参考文献

http://trasis.jp/blog/lab/2008/07/%E8%87%AA%E5%89%8D%E8%AA%8D%E8%A8%BC%E5%B1%80%E3%81%AEssl%E3%82%B5%E3%83%BC%E3%83%90.html
http://qiita.com/arai-wa/items/7ab1766da39e4ea441e3
http://d.hatena.ne.jp/stdcall/20060805/1154761291
* ちゃんとした認証を行うのに役立ちそう
http://apis.jpn.ph/fswiki/wiki.cgi?page=ScrapCode/Java/Https

API仕様

HostnameVerifier

ホスト名を検証するときの基本インタフェースです。
ハンドシェーク中に、検証メカニズムが URL のホスト名とサーバーの識別ホスト名に不一致を検出した場合は、
このインタフェースの実装側にコールバックし、この接続を許可するかどうかを確認します
https://docs.oracle.com/javase/jp/6/api/javax/net/ssl/HostnameVerifier.html

X509TrustManager

モート側のセキュアソケットの認証に使用される X.509 証明書を管理します。
使用される証明書は、信頼できる証明書発行局、証明書の取り消しリスト、オンライン状態チェックなどの方法に
基づいて決定されます。
https://docs.oracle.com/javase/jp/6/api/javax/net/ssl/X509TrustManager.html

関連記事

Java で、SSL通信を行うには

http://blogs.yahoo.co.jp/dk521123/33122920.html

Webサービス / Metro [8] ~ SSL通信を行う (2) / クライアントサイド ~

http://blogs.yahoo.co.jp/dk521123/36528991.html