Как загрузить .keystore с несколькими сертификатами в SpringBoot - PullRequest
0 голосов
/ 03 июля 2018

Я занимаюсь разработкой Spring Boot Application v2.0. Из моего приложения Spring Boot я отправляю SOAP-запрос на получение данных из Soap WS. У меня есть несколько запросов Soap к различным веб-службам Soap. Каждый Soap WS имеет свой собственный сертификат. Я использовал Apache CXF v3.2.4 для автоматической генерации классов "ws client" и всего остального для WS.

Сертификаты в формате PFX. Я успешно создал хранилище ключей через keytool. Я попытался настроить ssl.keyStore с помощью этого кода (также это не очень хороший способ установки этих значений, я предполагаю, что лучше сделать это в свойствах приложения ...:

System.setProperty("javax.net.ssl.keyStore","path to my keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "mypassword");

У меня в хранилище ключей 3 разных сертификата. Все они тестируются отдельно, и все они отлично работают, если они находятся только в хранилище ключей. Проблема в том, что когда у меня есть, например, 3 сертификата в хранилище ключей, загружается только первый в списке.

Я прочитал несколько статей в Интернете, эта статья была наиболее интересной, но, к сожалению, она не решила мою проблему ( Регистрация нескольких хранилищ ключей в JVM ).

Если я пройду через цепочку сертификатов по псевдониму, я смогу увидеть все сертификаты в консоли.

 String storename = "C:/Certificates/mykeystore.ks";
            char[] storepass = "mypassword".toCharArray();
            String alias = "myalias";
            KeyStore ks = KeyStore.getInstance("JKS");
            ks.load(new FileInputStream(storename), storepass);             
            java.security.cert.Certificate[] cchain = ks.getCertificateChain(alias);            
            List mylist = new ArrayList();
        for (int i = 0; i < cchain.length; i++) {                 
            mylist.add(cchain[i]);
            }
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            CertPath cp = cf.generateCertPath(mylist);
            System.out.println(cp);

У вас есть предложения ?! Что я должен сделать, чтобы достичь стадии, когда я могу загрузить одно хранилище ключей с несколькими сертификатами или все, что будет работать? Заранее спасибо.

p.s. Также я попытался поместить эти сертификаты в jdk / jre / lib / security / cacerts через Portecle, но безрезультатно.

1 Ответ

0 голосов
/ 04 июля 2018

Я думаю, что для каждой веб-службы вам следует обрабатывать хранилища ключей (и / или хранилища доверенных сертификатов) отдельно и настраивать их в файле application.properties. Ниже приведен работающий пример создания экземпляра SocketFactory для URL-соединения с конкретными наборами сертификатов.

application.properties

keystore1.Path = src/main/resources/jks/yourKeyStoreFile1
keystore1.Password = keystore1pwd
truststore1.Path = src/main/resources/security1/cacerts
truststore1.Password = truststore1pwd

keystore2.Path = src/main/resources/jks/yourKeyStoreFile2
keystore2.Password = keystore2pwd
truststore2.Path = src/main/resources/security2/cacerts
truststore2.Password = truststore2pwd

Когда вы используете другой WebService, используйте другой SocketFactory. Ниже приведен пример хранилища ключей .p12 и хранилища доверенных сертификатов .jks (сертификат). Вы можете легко конвертировать тип сертификата в другой формат.

@Component
public class MySocketFactory {

    @Value("${keystore1.Path}")
    String keystore1Path;

    @Value("${keystore1.Password}")
    String keystore1Password;

    @Value("${truststore1.Path}")
    String truststore1Path;

    @Value("${truststore1.Password}")
    String truststore1Password;

    public MySocketFactory() {

    }

    public SSLSocketFactory getSocketFactory() {

        try {

            SSLContext context = SSLContext.getInstance("TLS");

            KeyManagerFactory keyMgrFactory = KeyManagerFactory.getInstance("SunX509");
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            char[] keyStorePassword = keystore1Password.toCharArray();
            keyStore.load(new FileInputStream(keystore1Path), keyStorePassword);
            keyMgrFactory.init(keyStore, keyStorePassword);

            TrustManagerFactory trustStrFactory = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            KeyStore trustStore = KeyStore.getInstance("JKS");
            char[] trustStorePassword = truststore1Password.toCharArray();
            trustStore.load(new FileInputStream(truststore1Path), trustStorePassword);
            trustStrFactory.init(trustStore);

            context.init(keyMgrFactory.getKeyManagers(), trustStrFactory.getTrustManagers(), null);
            return context.getSocketFactory();

        } catch (Exception e) {
            System.err.println("Failed to create a server socket factory...");
            e.printStackTrace();
            return null;
        }
    }
}

Создайте то же самое для второго SocketFactory. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...