我正在尝试编写一种方法,给定连接和搜索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对象吗?
答案 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