LoginSignup
7
8

More than 5 years have passed since last update.

JavaからLDAPSで「unable to find valid certification path to requested target」とエラーになる現象に遭遇しました

Posted at

JavaでLDAPS(LDAP over SSL/TLS)をやりたくて実験プログラムを作ったところ、以下のようなエラーに遭遇しました。

Javaエラーメッセージ
Lookup failed: javax.naming.CommunicationException: simple bind failed: Samba4サーバ:636 [Root exception is 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]

結果からの推測ですが、デフォルトのキーストア(jre/lib/security/cacrts)であってもVM引数かJAVA_OPTSで指定する必要があるようです。

以下、参考までに実験プログラムとキーストアにサーバ証明書(公開鍵)を登録する方法を記しておきます。

実験プログラム

実験ソース
import java.util.Hashtable;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class App {
  public static void main(String args[]) {
    final String username = "user3";

    Hashtable<String, String> env = new Hashtable<String, String>();
    env.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, username + "@devel.local");
    env.put(Context.SECURITY_CREDENTIALS, "User3###");
    env.put(Context.PROVIDER_URL, "ldaps://Samba4サーバ:636");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PROTOCOL, "ssl");

    DirContext ctx;
    try {
      ctx = new InitialDirContext(env);
      Attributes attrs = ctx
        .getAttributes("CN=user3,CN=Users,DC=devel,DC=local");

      if (attrs != null) {
        try {
          for (NamingEnumeration ae = attrs.getAll(); ae.hasMore();) {
            Attribute attr = (Attribute) ae.next();
            System.out.println("attribute: " + attr.getID());
            for (NamingEnumeration e = attr.getAll(); e.hasMore(); 
              System.out.println("value: " + e.next()));
          }
        } catch (NamingException e) {
          e.printStackTrace();
        }
      }
      ctx.close();
    } catch (AuthenticationException e) {
      System.out.println("Invalid credentials");
    } catch (NamingException e) {
      System.out.println("Lookup failed: " + e);
    }
  }
}

キーストアにサーバの自己証明書を登録する方法

サーバの自己証明書を作成する(サーバ)

末尾に示す「Samba4のための自己証明書の作成方法」を参考にして、サーバの自己証明書を作成します。そのファイルはmyCert.pemとします。

サーバの自己証明書をキーストアに登録する(クライアント)

サーバで作ったmyCert.pemを%JAVA_HOME%\jre\lib\securityにコピーした後、以下のコマンドでインポートします。

Windowsのコマンドプロンプトにて
cd %JAVA_HOME%\jre\lib\security
keytool -keystore cacerts -importcert -alias surnet-samba-ad -file myCert.pem

エリアスに指定した名前(surnet-samba-ad)は何でもいいと思います。キーストアはデフォルトのキーストアを指定しましたが、新しく作ってもいいと思います。

実験プログラムを実行する

実験プログラムを実行する前に、JAVA_OPTSにキーストアを指定しておきます。

実験プログラムを実行する前に
set JAVA_OPTS="-Djavax.net.ssl.trustStore=%JAVA_HOME%\jre\lib\security\cacerts -Djavax.net.ssl.trustStorePassword=changeit"

参考

7
8
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
7
8