Как настроить apache httpclient 4.5+ SSLContext для использования взаимной аутентификации TLS с самозаверяющим сертификатом? - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь настроить CloseableHttpClient из httpclient 4.5 с взаимной аутентификацией TLS. Сертификат сервера самоподписан. Вот код, который я использую (вдохновленный различными сообщениями StackOverflow):

KeyStore trustStore = KeyStore.getInstance("pkcs12");
try (InputStream fis = new FileInputStream(ssl_cert_file)) {
    trustStore.load(fis, password.toCharArray());
}
SSLContext sslContext = SSLContexts.custom()
        .loadKeyMaterial(trustStore, password.toCharArray(), (map, socket) -> "client")
        .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
        .build();
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext,  new DefaultHostnameVerifier());
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("https", socketFactory).build();
connectionManager = new PoolingHttpClientConnectionManager(registry);

Я получил

sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target

Похоже, что сертификат CA, который я предоставляю, не используется, я думаю. Любая идея о том, что может быть не так?


Сертификат CA, сертификат клиента и личный ключ клиента находятся в файле pkcs12, созданном с помощью

openssl pkcs12 -export -in client-cert.pem -inkey private/client-key.pem -certfile cacert.pem -name "client" -out client-cert.p12

Я попытался openssl s_client проверить сертификат возвращает ожидаемый результат (он делает). Я подозреваю, что проблема связана с моим кодом, а не с client-cert.p12 файлом.

openssl s_client -connect host:port -tls1 -cert client-cert.pem -key private/client-key.pem -CAfile cacert.pem

1 Ответ

1 голос
/ 18 февраля 2020

Как указал @Gimby Проблема заключалась в том, что сертификат моего ЦС не был распознан как TrustCertEntry в моем хранилище ключей.

Мой обходной путь - создать файл jks только для сертификата ЦС:

keytool -import -alias client -file cacert.pem -storetype JKS -keystore cacert.jks

Создайте из него объект KeyStore и используйте его для SSLContext.loadTrustMaterial.

...