Я слишком долго и долго искал решение проблемы.
Я пытаюсь сделать взаимный SSL.Цель использует сертификат, подписанный посредником, который является действительным и доверенным.Моя сторона, клиент веб-службы Java, использующий httpclient 4.3.6, также использует сертификат, подписанный промежуточным продуктом.
Промежуточный продукт находится в хранилище ключей формата JKS и имеет полную цепочку.Мой сертификат также находится в хранилище ключей JSK.
Я также использую Wireshark, чтобы следить за процессом SSL, поскольку исключения Java очень бесполезны.Я вижу, что Сервер Hello завершает работу (строка в Wireshark называется «Сервер Hello, Сертификат, Обмен ключами сервера, Запрос сертификата, Сервер Hello Done»).Пару пакетов позже, есть строка «Сертификат, Обмен ключами клиента», которая , кажется, работает нормально.Через два пакета появляется предупреждение о сбое рукопожатия (40).Когда я возвращаюсь назад на два пакета к строке «Сертификат, Обмен ключами клиента» и внимательно его проверяю, я вижу, что, пока ключ был отправлен, в окне проверки пакетов есть строка «Длина сертификата: 0».
Итак, похоже, что мой сертификат даже не отправляется?В другом вопросе я увидел, что это может быть из-за того, что моя сторона не видит правильный путь к моему сертификату, и поэтому не стоит включать его?(Ответ здесь https://stackoverflow.com/a/14876605/5136448). Я включаю хранилище доверия, в котором есть мое промежуточное звено при использовании SSLContext и SSLConnectionSocketFactory.
Мой коллега получил успешное соединение с использованием openssl, когда включил мое хранилище ключей и промежуточное соединениевместе, поэтому я пытаюсь добавить цепочку сертификатов из промежуточного хранилища ключей в свое собственное хранилище ключей, чтобы посмотреть, решит ли это это. Я не нашел никакого успешного способа сделать это (openssl, keytool, Keystore Explorer), поэтому я могуне имею правильного представления о том, как правильно решить эту проблему.
Подводя итог, используя Apache http-клиент 4.3.6, мне нужно сделать взаимный SSL для сервера, которому доверяют, но клиент не 'Кажется, он отправляет свой сертификат (который был подписан тем же объектом, который подписал сертификат сервера).
Если это уместно, вот код на стороне клиента:
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(new FileInputStream(new File("/path/to/test.keystore")), "abc123".toCharArray());
KeyStore trustStore = KeyStore.getInstance("PKCS12");
trustStore.load(new FileInputStream(new File("/path/to/test.truststore")), "123abc".toCharArray());
SSLContext sslContext = SSLContexts
.custom()
.loadKeyMaterial(keystore, "abc123".toCharArray(), null)
.loadTrustMaterial(trustStore, null)
.build();
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
new String[]{"TLSv1.2"},
null,
SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient1 = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();