如何从LDAP服务器(Java)读取证书属性(caCertificate)?

时间:2016-06-14 07:06:13

标签: java ldap certificate jndi x509certificate

我正在尝试编写一种方法,给定连接和搜索LDAP的信息(例如,主机名,基本DN等),可以检索包含CA证书的属性(“caCertificate”属性)

我已经看到了一些关于如何做到这一点的建议,但到目前为止还没有能够让人工作。

我认为我能够进行LDAP搜索和检索,但却无法弄清楚如何处理作为证书属性值的字节数组。

以下是我认为正在运作的部分的片段:

        Date theReturnedDate = null;
        String base = "ou=CAs,dc=test,dc=com";
        String filter = "(objectclass=CertificationAuthority)";

        System.out.println("In LDAPUpdate.checkReadLdap: Entering, theLdapCn = [" + theLdapCn + "]...");
    Hashtable envRead = new Hashtable(11);
    envRead.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    envRead.put(Context.PROVIDER_URL, "ldap://my.test.ldap:389");
    envRead.put(Context.SECURITY_AUTHENTICATION, "simple");
    envRead.put(Context.SECURITY_PRINCIPAL, "cn=admin,ou=people,dc=test,dc=com");
    envRead.put(Context.SECURITY_CREDENTIALS, "xxx"); 
    //specify attributes to be returned in binary format
    envRead.put("java.naming.ldap.attributes.binary","caCertificate");


    SearchControls searchCtls = new SearchControls();
    //Specify the attributes to return
    String returnedAtts[]={"caCertificate"};
    searchCtls.setReturningAttributes(returnedAtts);

    DirContext ctx = null;
        try
    {
        // Create the initial directory context
        InitialDirContext initialContext = new InitialDirContext(envRead);
        ctx = (DirContext)initialContext;

        System.out.println("Context Sucessfully Initialized");

        SearchControls constraints = new SearchControls();
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

        NamingEnumeration results = ctx.search(base, filter, constraints);

        while(results != null && results.hasMore())
        {
            SearchResult sr = (SearchResult) results.next();
            String dn = sr.getName() + "," + base;
            System.out.println("Distinguished Name is " + dn);

            Attributes ar = ctx.getAttributes(dn, returnedAtts);

            if(ar == null)
            {
                System.out.println("Entry " + dn);
                System.out.println(" has none of the specified attributes\n");
            }
            else
            {
                System.out.println("In LDAPUpdate.readCheckLdap: returnedAtts.length=[" + returnedAtts.length + "]");
                for(int i=0; i<returnedAtts.length; i++)
                {
                    Attribute attr = ar.get(returnedAtts[i]);
                    System.out.println(returnedAtts[i] + ":");

                    for(Enumeration vals=attr.getAll(); vals.hasMoreElements();)
                    {
                        System.out.println("\t" + vals.nextElement());
                    }
                }
            }
        }
    }
    catch(Exception e)
    {
        System.err.println(e);
    }

任何人都可以告诉我如何做我需要的其余部分,即获取随CA证书返回的属性并将其转换为X509Certificate对象吗?

2 个答案:

答案 0 :(得分:1)

  

任何人都可以告诉我如何完成我需要的其余部分,即获取随CA证书返回的属性并将其转换为X509Certificate对象吗?

这样的事情:

import java.io.ByteArrayInputStream;
import java.security.cert.*;

CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(new ByteArrayInputStream(bytes));

E&安培; OE

答案 1 :(得分:1)

我认为我得到了它的工作!

记录中,这是完整的工作示例。我在那里留下了一些可能有用的调试代码。这将绑定到LDAP服务器,然后检索条目,然后将caCertificate属性提取到X509Certificate对象中。然后,它显示X509Certificate中的Subject DN,以测试该对象是否已实例化。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;


public class GoodReadACertFromLdap{

public static void main(String[] args) {

    System.out.println("This Java application demonstrates how to retrieve a caCertificate object from an LDAP server");

    Hashtable env = new Hashtable(11);
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://myldapserver:389/");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, "cn=directory manager");
    env.put(Context.SECURITY_CREDENTIALS, "XXXX");
    Object cert = null;
    Attributes attrs = null;
    Attribute attr = null;

      try {
            LdapContext ctx = new InitialLdapContext(env, null);
            ctx.setRequestControls(null);
            NamingEnumeration<?> namingEnum = ctx.search("CN=mycert,ou=CAs,dc=whatever,dc=com", "(objectclass=*)", getSimpleSearchControls());
            while (namingEnum.hasMore ()) {
                SearchResult result = (SearchResult) namingEnum.next ();    
                attrs = result.getAttributes ();
                System.out.println(attrs.get("cn"));
                cert = attrs.get("caCertificate;binary");
                System.out.println(cert);
                System.out.println(attrs.get("objectclass"));

            } 
            namingEnum.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

      if (((Attribute)cert).size() == 0) {
          System.out.println("The cert attribute was cert.size == 0!");
          System.exit(0);
      }

      System.out.println("The cert attribute cert.size was NOT 0, so will now try to make it into a certificate object!");
      System.out.println("The cert attribute cert.size was: [" + ((Attribute)cert).size() + "]");
      System.out.println("Here's cert again: [" + cert + "]");

      try {
          X509Certificate certOut = null;
          CertificateFactory cf = CertificateFactory.getInstance("X.509");

          attr = attrs.get("caCertificate;binary");     // get the caCertificate attribute so we can make a NamingEnumeration from it...
          for (NamingEnumeration e = attr.getAll();e.hasMore();) {
            try {
                 ByteArrayInputStream bais = new ByteArrayInputStream( (byte[])e.next());
                 certOut = (X509Certificate)cf.generateCertificate(bais);
            } catch (Exception ex ) {
                System.out.println("While converting Attribute object to a X509Certificate, EXCEPTION = " + ex);
            } // end catch()
          }

          System.out.println("certOut.getSubjectDN = [" + certOut.getSubjectDN() + "]");


      } catch (Exception e) {
          e.printStackTrace();
      }

} // end main()



private static SearchControls getSimpleSearchControls() {
    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    searchControls.setTimeLimit(30000);
    String[] attrIDs = {"cn", "caCertificate", "objectclass"};
    searchControls.setReturningAttributes(attrIDs);
    return searchControls;
} // end getSimpleSearchControls()



} // end CLASS