当前位置: 首页 > 面试题库 >

如何接受JNDI / LDAP连接的自签名证书?

宗政招
2023-03-14
问题内容

我需要通过SSL连接到LDAP目录。

在非生产环境中,我们使用自签名证书,这些证书当然无法通过以下方式进行验证:

javax.naming.CommunicationException: simple bind failed: ldapserver: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]
 at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:197)
 at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2694)
 at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:293)
 at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
 at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
 at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
 at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
 at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
 at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
 at javax.naming.InitialContext.init(InitialContext.java:223)
 at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:134)

我知道如何对启用S​​SL的连接使用[自定义信任管理器]http://codingdict.com/questions/1835),但是不知道如何在不管理实际连接的情况下与JNDI
API结合使用。也就是说,我可以在哪里在以下标准设置下插入信任管理器?

提前致谢。

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldaps://ldapserver:636");
env.put(Context.SECURITY_PROTOCOL, "ssl");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "myUser");
env.put(Context.SECURITY_CREDENTIALS, "myPassword");
LdapContext ctx = new InitialLdapContext(env, null);
ctx.search (...)

问题答案:

根据JNDI文档,似乎可以设置自定义 SSLSocketFactory

http://download.oracle.com/javase/1.5.0/docs/guide/jndi/jndi-ldap-
gl.html#socket

public class MySSLSocketFactory extends SocketFactory {
    private static final AtomicReference<MySSLSocketFactory> defaultFactory = new AtomicReference<>();

    private SSLSocketFactory sf;

    public MySSLSocketFactory() {
        KeyStore keyStore = ... /* Get a keystore containing the self-signed certificate) */
        TrustManagerFactory tmf = TrustManagerFactory.getInstance();
        tmf.init(keyStore);
        SSLContext ctx = SSLContext.getInstance("TLS");
        ctx.init(null, tmf.getTrustManagers(), null);
        sf = ctx.getSocketFactory();
    }

    public static SocketFactory getDefault() {
        final MySSLSocketFactory value = defaultFactory.get();
        if (value == null) {
            defaultFactory.compareAndSet(null, new MySSLSocketFactory());
            return defaultFactory.get();
        }
        return value;
    }

    @Override
    public Socket createSocket(final String s, final int i) throws IOException {
        return sf.createSocket(s, i);
    }

    @Override
    public Socket createSocket(final String s, final int i, final InetAddress inetAddress, final int i1) throws IOException {
        return sf.createSocket(s, i, inetAddress, i1);
    }

    @Override
    public Socket createSocket(final InetAddress inetAddress, final int i) throws IOException {
        return sf.createSocket(inetAddress, i);
    }

    @Override
    public Socket createSocket(final InetAddress inetAddress, final int i, final InetAddress inetAddress1, final int i1) throws IOException {
        return sf.createSocket(inetAddress, i, inetAddress1, i1);
    }
}

配置环境以使用此套接字工厂

env.put("java.naming.ldap.factory.socket", "com.example.MySSLSocketFactory");


 类似资料:
  • 使用Git,有没有办法告诉它接受自签名证书? 我使用https服务器来托管git服务器,但目前证书是自签名的。 当我第一次尝试在那里创建回购时: 我得到的错误:

  • 问题内容: 如何在Android上的Java中接受自签名证书? 一个代码示例将是完美的。 我在Internet上到处都是,虽然有人声称找到了该解决方案,但它要么不起作用,要么没有示例代码来对其进行备份。 问题答案: 我在exchangeIt中具有此功能,该功能可通过WebDav连接到Microsoft Exchange。这是一些创建HttpClient的代码,该HttpClient将通过SSL连接

  • 我正在使用AWS API网关和一个后端。为了确保所有的连接都通过API网关,我需要使用TLS客户端身份验证(又名双向身份验证,相互身份验证)。 原则上,这与以下内容一起工作: 我遇到的问题是这个错误: TLS:无法验证客户端的证书:X509:由未知授权机构签署的证书(可能是因为在尝试验证候选授权机构证书“Apigateway”时“X509:签名无效:父证书无法签署此类证书”)

  • 我们的应用程序可以使用Active Directory用户和组。我们在端口389上使用LDAP进行Active Directory操作。现在,我们的一个客户机希望我们添加一个使用LDAP+SSL进行Active Directory通信的选项。 他们告诉我们,他们在域上安装了一个本地CA,并对LDAP使用自签名证书。他们还告诉我们,他们会提供证书,不需要相互信任,我们应该使用Windows证书存储。

  • 我的手被https、ssl、PKI之类的东西弄得脏兮兮的。对于自签名证书,有一点我不太理解。假设我想创建一个自签名证书,并在我们想要建立安全连接时将其发送给我的朋友。 所以步骤是: 创建一个私钥。 创建一个公钥。 用我的公钥在证书上签名。 因此,当我的朋友得到我的证书时,他必须验证他得到的证书是我的,他需要解密数字签名。但为了解密和验证他必须拥有我的私钥。所以,我有点困惑。