Хранилище ключей Inmemory с использованием API хранилища ключей 'не может найти действительный путь сертификации для запрашиваемой цели' - PullRequest
0 голосов
/ 20 сентября 2019

Я пытаюсь создать хранилище ключей памяти для одного запроса 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, но вместо этого я «не могу найти правильный путь сертификации для запрошенной цели»

1 Ответ

0 голосов
/ 24 сентября 2019

Мне удалось решить эту проблему.Код работает правильно, проблема была в том, что мы использовали самозаверяющий сертификат, который невозможно проверить.Все, что нам нужно было сделать, это поместить сертификат hte в файл cacerts.Самозаверяющие сертификаты являются их собственным центром сертификации, и поэтому они должны быть помещены в файл cacerts, файл находится в каталоге $ JAVA_HOME / jre / lib / security / cacerts.

...