2017-02-01 5 views
0

Мое приложение является веб-провайдером, работающим на веб-сервере, а клиент веб-службы SOAP состоит из нескольких хранилищ ключей, специфичных для каждого клиента. Приложение должно быть перенесено в tomcat, и я поражен, так как мне нужно использовать разные сертификаты для установления соединения TLS с сервером back-end на основе входящего запроса клиента.Dynamic SSL Keystore/Certificate selection

Я использую springboot и имею способ настройки хранилище ключей и доверенное лицо. Далее следуют ниже ссылке:

http://zoltanaltfatter.com/2016/04/30/soap-over-https-with-client-certificate-authentication/

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

Но у меня был какой-то другой подход, скажем, я держу все сертификаты в одном хранилище ключей, как мы можем динамически обращаться к клиентскому сертификату?

ответ

0

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

По умолчанию KeyManager выберет первый сертификат в рукопожатии, поэтому перед созданием соединения нет необходимости создавать свой собственный X509KeyManager, чтобы указать псевдоним, который будет использоваться. См How I can tell alias of the wanted key-entry to SSLSocket before connecting?

KeyStore keystore = ... //The keystore with all your certificates 

//The keymanager for an specific connection 
KeyManagerFactory kmf= KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
kmf.init(keystore, password.toCharArray()); 

//Create a keyManager wrapper that returns the alias to use 
final X509KeyManager origKm = (X509KeyManager)kmf.getKeyManagers()[0]; 
X509KeyManager km = new X509KeyManager() { 
    public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) { 
     return "alias"; 
    } 

    public X509Certificate[] getCertificateChain(String alias) { 
     return origKm.getCertificateChain(alias); 
    } 

// override the rest of the methods delegating to origKm ... 
} 

Вводят новый keyManager в HttpsUrlConnectionMessageSender

HttpsUrlConnectionMessageSender messageSender = new HttpsUrlConnectionMessageSender(); 
//messageSender.setKeyManagers(keyManagerFactory.getKeyManagers()); 
messageSender.setKeyManagers(new KeyManager[] { km }); 
+0

Я попробовал ваш подход, он работал, но я столкнулся с другой проблемой. Я объявил X509Keymanager и переопределил вышеупомянутые два метода, но когда я сделал звонок на целевой сервер, я получил следующее сообщение об ошибке: main, RECV TLSv1.2 ALERT: фатальный, неожиданный_message main, обработка исключений: javax.net.ssl .SSLException: получена фатальная ошибка. Я исправил эту ошибку, предоставив объект KeyManager для HttpsUrlConnectionMessageSender вместо X509KeyManager. Трассировка SSL сервера показывает, что сервер не получает сообщение _CERTIFICATE-VERIFY_ от клиента, поэтому соединение прерывается внезапно. – user3709612

+0

Точная ошибка: 'Caused by: org.springframework.ws.client.WebServiceIOException: Ошибка ввода-вывода: полученное фатальное предупреждение: unexpected_message; Вложенное исключение - это javax.net.ssl.SSLException: Получено фатальное предупреждение: неожиданный_message \t at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive (WebServiceTemplate.java:561) ~ [spring-ws-core-2.3.1 .RELEASE.jar: 2.3.1.RELEASE] ..... Вызвано: javax.net.ssl.SSLException: получено фатальное предупреждение: неожиданное_значение \t at sun.security.ssl.Alerts.getSSLException (Alerts.java:208) ~ [na: 1.8.0_71] ' – user3709612

+0

Я исправил проблему, похоже, что мое приложение извлекает закрытый ключ как null, поскольку я не переопределял метод. Это исправление: '@Override \t \t \t общественного PrivateKey getPrivateKey (String arg0) { \t \t \t \t // TODO Auto-генерироваться метод заглушки \t \t \t \t возвращение origKm.getPrivateKey (arg0); \t \t \t} ' – user3709612