Let’s Encrypt証明書での接続エラー

XSERVER、Zenlogic、などでLet’s Encryptの証明書が手軽に無料で使えるようになっています。
今後も利用はどんどん広がっていくと思いますが、Javaの世界ではそうでもないようです。

 

Let’s Encrypt & Java8 update77での接続

手元にJava8 update77の環境があるのでLet’s Encryptの証明書を設定してあるXSERVERのHTTPサーバーに接続してみます。
コードは以下の通り検証するだけのものです。
何の実用性もなくてすいません。

package test;

import java.net.URL;

public class SSLTest {
	public static void main(String[] args) throws Exception {
		
		URL url = new URL("https://host_with_lets_encrypt/");
		url.openConnection().connect();
		
		System.out.println(url.getHost());

	}
}

実行した結果、以下のExceptionが吐かれました。

Exception in thread "main" 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
	at sun.security.ssl.Alerts.getSSLException(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
	at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
	at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
	at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
	at sun.security.ssl.Handshaker.processLoop(Unknown Source)
	at sun.security.ssl.Handshaker.process_record(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
	at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
	at test.SSLTest.main(SSLTest.java:8)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
	at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
	at sun.security.validator.Validator.validate(Unknown Source)
	at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
	at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
	at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
	... 12 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
	at java.security.cert.CertPathBuilder.build(Unknown Source)
	... 18 more

このエラーを見ると、Javaのクライアント側に証明書を作って入れたくなりますが、ちょっと我慢してみましょう。

 

googleのホスト & Java8 update77での接続

続いて、googleに接続してみます。
Googleの証明書の発行者は・・・Googleですね。
先ほどの接続先をhttps://www.google.co.jp/に変更しただけです。

package test;

import java.net.URL;

public class SSLTest {
	public static void main(String[] args) throws Exception {
		
		URL url = new URL("https://www.google.co.jp/");
		url.openConnection().connect();
		
		System.out.println(url.getHost());

	}
}

実行結果は以下のとおり、正常に接続できました。

www.google.co.jp

 

Let’s Encrypt & Java8 update102での接続

続いて、最新のJDK、Java8 update102で試してみましょう(2016年7月29日現在)。
Let’s Encryptの証明書が設定してあるホストへの接続結果です。

host_with_lets_encrypt

正常に接続できました。
ホスト名は書き換えているわけですけれど。

 

対処方法について

Let’s Encryptの証明書はJava 8 Update101からサポートされているようです。
https://www.java.com/ja/download/faq/release_changes.xml
identrustがルートCAに追加されているのがそれですね。

https://letsencrypt.org/certificates/

しかし、Java 8 Update101がリリースされたのは2016年7月19日のことで、既存システムのJREを置き換える作業がそれほど進むとは思えません。
今後しばらくはJavaからの接続が必要なシステムは、接続元に証明書を追加するか、従来の証明書を購入する必要があるでしょう。

特にレンタルサーバーなどではchain.pemの入手も困難だと思いますので、証明書を購入するのが確実だと思います。

 
最近ではWordPressでサイト構築した際にSSL化するケースも多いかと思いますが、SmartNewsなどにフィードを提供している方、ご注意下さい。