首页 > 解决方案 > 使用密钥库 api 的内存密钥库“无法找到到所请求目标的有效证书路径”

问题描述

我正在尝试为单个 ldap 请求创建一个内存密钥库。Ldap 连接和证书可以更改,因此我无法将它们存储在任何地方。

Spring Ldap 对多个 ldap 连接不是很友好

    public LdapContextSource buildLdapContext(final LdapConnection connection) {
        final LdapContextSource context = new LdapContextSource();
        context.setBase(connection.getBaseDN());
        context.setUrl(connection.getConnectionUrl());
        context.setPassword(connection.getAdminPassword());
        context.setUserDn(connection.getUserDN());

        if(connection.getProtocol() == LdapProtocol.LDAPS) {
            final DefaultTlsDirContextAuthenticationStrategy authenticationStrategy = new DefaultTlsDirContextAuthenticationStrategy();
            authenticationStrategy.setSslSocketFactory(ldapSslSocketFactoryBuilder.buildSslSocketFactory(connection));
            context.setAuthenticationStrategy(authenticationStrategy);
        }

        context.afterPropertiesSet();
        return context;
    }
    public SSLSocketFactory buildSslSocketFactory(final LdapConnection connection) {
        try {
            final KeyStore store = buildKeyStore(connection);
            final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(store);

            final SSLContext ctx = SSLContext.getInstance("SSL");
            ctx.init(null, tmf.getTrustManagers(), null);
            return ctx.getSocketFactory();

        } catch(Exception e) {
            throw new LdapException(e.getMessage(), e);
        }
    }
    private KeyStore buildKeyStore(final LdapConnection ldapConnection) {
        try {
            // Load in-memory keystore
            final KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystore.load(null);

            // Decode certificate
            byte[] decoded = Base64.decodeBase64(ldapConnection.getSslCertificate()
                            .replaceAll(X509Factory.BEGIN_CERT, "")
                            .replaceAll(X509Factory.END_CERT, "")
                            .trim().getBytes(StandardCharsets.UTF_8));

            // Load certificate
            CertificateFactory certificateFactory = CertificateFactory.getInstance("x.509");
            Certificate cert = certificateFactory.generateCertificate(new ByteArrayInputStream(decoded));
            keystore.setCertificateEntry(ldapConnection.getConnectionUrl(), cert);

            return keystore;
        } catch(Exception e) {
            log.error(e.getMessage(), e);
            throw new LdapException(e.getMessage(), e);
        }
    }

我希望存储的公钥用于连接到 ldap 服务器,但我得到“无法找到请求目标的有效证书路径”

标签: javaspringsslldapspring-ldap

解决方案


我设法解决了这个问题。该代码正常工作,问题是我们使用的是无法验证的自签名证书。我们所要做的就是将 hte 证书放入 cacerts 文件中。自签名证书是他们自己的证书颁发机构,因此必须放入 cacerts 文件中,该文件位于 $JAVA_HOME/jre/lib/security/cacerts。


推荐阅读