Tomcat6でSSL SSLの認証を省略

前回まででJavaとTomcatサーバー間のSSL通信は可能となったが、やや難点がある。
localhostサーバーの証明書に有効期限があるのだ。
keytoolのデフォルトでは90日である。
定期的な証明書の交換が必要だ。
メンテナンスの発生である。
特定のサーバーとのやり取りであるならいちいち認証するのは不要に思う。
調べてみると省略する方法があった。
静的な定義と生成したコネクションに対する操作で認証手続きを省略できる。

static {
  try {
    HttpsURLConnection.setDefaultHostnameVerifier(
      new HostnameVerifier() {
        public boolean verify(String host, SSLSession ses) {
          return true;
        }
      }
    );
  } catch (Exception e) {
    e.printStackTrace();
  }
}
private void setIgnoreCertificateValidation(
  HttpURLConnection con) {
  if(con instanceof HttpsURLConnection) {
    KeyManager[] km = null;
    TrustManager[] tm = {
      new X509TrustManager() {
        public void checkClientTrusted(
            X509Certificate[] arg0, String arg1)
            throws CertificateException {}
        public void checkServerTrusted(
            X509Certificate[] arg0, String arg1)
            throws CertificateException {}
        public java.security.cert.X509Certificate[] 
               getAcceptedIssuers() { return null; }
        @Override
        public void checkClientTrusted(
            java.security.cert.X509Certificate[] arg0,
            String arg1)
            throws java.security.cert.CertificateException {
        }
        @Override
        public void checkServerTrusted(
            java.security.cert.X509Certificate[] arg0,
            String arg1)
            throws java.security.cert.CertificateException {
        }
      }
    };
    try {
      SSLContext sslcontext= SSLContext.getInstance("SSL");
      sslcontext.init( km, tm, new SecureRandom() );
      ((HttpsURLConnection)con).setSSLSocketFactory(
          sslcontext.getSocketFactory());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

コネクションを行う前に上記で定義したsetIgnoreCertificateValidationをコールすればOKだ。

try {
  URL url = new URL("https://localhost:8443");
  HttpURLConnection con = 
         (HttpURLConnection)url.openConnection();
  if(con != null) {
    setIgnoreCertificateValidation(con); // 追加
    con.connect();
    InputStreamReader in = 
    new BufferedReader(
        new InputStreamReader(con.getInputStream()));
    String str;
    while((str = in.readLine()) != null) {
      System.out.println(str);
    }
    in.close();
    con.disconnect();
  }
} catch(Exception e) {
  e.printStackTrace();
}

これで認証が省略されるのでVM引数で渡していたトラストストア(javax.net.ssl.trustStoreとjavax.net.ssl.trustStorePassword)も不要になる。
メンテナンスの発生は回避された。
但し、プロキシ経由でブロックされることがあります。
あしからず・・・。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です