java - 使用 keystore api 'unable to find valid certification path to requested target' 的内存 keystore

标签 java spring ssl ldap spring-ldap

我正在尝试为单个 ldap 请求创建内存中的 keystore 。 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 服务器,但我却得到“无法找到到请求目标的有效证书路径”

最佳答案

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

关于java - 使用 keystore api 'unable to find valid certification path to requested target' 的内存 keystore ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58028239/

相关文章:

java - Java 对 WPF 的回答是什么?

spring - 如何在 r2dbc-postgresql 中使用 EnumCodec

encryption - 从一个站点到另一个站点的 SSL 表单 POST

php - file_get_contents() 在不同机器上的工作方式不同

java - 如何设置其他包无法访问该包

java - 如何使用 DeepLearning4J 训练 RBM 和重建输入?

java - 没有符合条件的 ScheduledExecutorService 类型的 bean |任务调度器

java - web.servlet.PageNotFound ,请求方法 'GET' 不支持,Spring

linux - Linux 上的 Squeak SMTP

java - 使用 java.util.Scanner 解析基本类型