如何使用p12证书连接LDAP服务器

3 投票
2 回答
4937 浏览
提问于 2025-04-15 18:50

我想用一个 .p12 证书来连接 LDAP 服务器,而不是用用户名和密码。用 Java 实现这个功能的代码看起来是这样的:

String ldapURL = "ldaps://"+host+":"+port;   

System.setProperty("javax.net.ssl.keyStoreType", "PKCS12" );  
System.setProperty("javax.net.ssl.keyStore",keystore);
System.setProperty("javax.net.ssl.keyStorePassword", keystorePassword);   

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, ldapURL);
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.REFERRAL, "follow");

try 
{
    // Create initial context
    LdapContext ctx = new InitialLdapContext(env, null);
    // Perform client authentication using TLS credentials
    ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "EXTERNAL");

    SearchControls ctls = new SearchControls();
    // Specify the search filter to match
    String filter = "(objectClass=*)";
    // Search for objects using the filter
NamingEnumeration answer = ctx.search("ou="+elemType[i]+","+siteSpecificBaseDN, filter, ctls);

...

我能用 Python 做同样的事情吗?我只找到了一些示例,展示了如何用 python-ldap 通过用户名和密码连接到 LDAP 服务器,但这不是我需要的。如果不能用 .p12 证书,那如果有用 x509 证书(.pem 格式)的解决方案也对我有帮助。

2 个回答

0

看起来 ldaptor 可以给你提供这个功能。它是基于 twisted 这个框架构建的,而 twisted 自带对 SSL 的支持,这个支持在 twisted.internet.ssl 模块里。

你可以看看这个: ldaptor.protocols.ldap.ldapclient.startTLS()

2

如果你使用python-ldap库,可以通过TLS选项来设置相关参数。

ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, "/path/to/trustedcerts.pem")
ldap.set_option(ldap.OPT_X_TLS_CERTFILE, "/path/to/usercert.pem")
ldap.set_option(ldap.OPT_X_TLS_KEYFILE, "/path/to/user.key.pem")

ds = ldap.initialize("ldaps://ldap.example.com:port/")
# If using START_TLS instead of ldaps:
# ds = ldap.initialize("ldap://ldap.example.com:port/")
# ds.start_tls_s()

在这种情况下:

  • trustedcerts.pem相当于信任存储。它是你想要的受信任证书的集合,格式为PEM。你也可以使用一个包含单个证书的目录,通过OPT_X_TLS_CACERTFILE来指定,但我认为这在GnuTLS中不被支持,所以这取决于python-ldap和它的OpenLDAP客户端库是用哪个TLS库编译的。关于底层指令的更多细节,可以参考OpenLDAP手册
  • usercert.pem是你的用户证书,格式为PEM(你需要从你的PKCS#12文件中提取它)。
  • user.key.pem是你的私钥(同样,它需要从p12文件中提取)。

从PKCS#12文件中提取证书和密钥可以使用OpenSSL,命令如下:

openssl pkcs12 -in userstore.p12 -clcerts -nokeys -out usercert.pem
openssl pkcs12 -in userstore.p12 -nocerts -nodes -out user.key.pem

注意:如果你用这种方式提取私钥(在user.key.pem中,使用-nodes),它将不会有密码保护,所以你需要确保这个文件对其他人不可读。我认为OpenLDAP(更不用说它的Python绑定)不允许你以交互方式输入密码来解决这个问题,但我不太确定。

撰写回答