Наконец-то удалось решить все вопросы, поэтому я отвечу на свой вопрос. Это настройки / файлы, которые я использовал для решения своих проблем;
В хранилище ключей клиента является формат PKCS # 12 файл , содержащий
- Публичный сертификат клиента (в данном случае подписанный самозаверяющим центром сертификации)
- Клиентский частный ключ
Для генерации я использовал pkcs12
команду OpenSSL , например;
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "Whatever"
Совет: убедитесь, что вы получили последнюю версию OpenSSL, а не версию 0.9.8h, потому что, похоже, она страдает от ошибки, которая не позволяет правильно генерировать файлы PKCS # 12.
Этот файл PKCS # 12 будет использоваться клиентом Java для представления сертификата клиента серверу, когда сервер явно запросил у клиента аутентификацию. См. Статью в Википедии о TLS для обзора того, как на самом деле работает протокол для аутентификации сертификата клиента (здесь также объясняется, почему нам нужен закрытый ключ клиента).
В доверенном хранилище клиента является прямым JKS формат файл , содержащий корень или промежуточного ЦСА сертификатов . Эти сертификаты CA будут определять, с какими конечными точками вам будет разрешено общаться, в этом случае ваш клиент сможет подключиться к тому серверу, на котором будет представлен сертификат, который был подписан одним из центров доверенных сертификатов.
Для его генерации вы можете использовать стандартный Java keytool, например;
keytool -genkey -dname "cn=CLIENT" -alias truststorekey -keyalg RSA -keystore ./client-truststore.jks -keypass whatever -storepass whatever
keytool -import -keystore ./client-truststore.jks -file myca.crt -alias myca
Используя это доверенное хранилище, ваш клиент попытается выполнить полное рукопожатие SSL со всеми серверами, которые представляют сертификат, подписанный ЦС, идентифицированным myca.crt
.
Приведенные выше файлы предназначены исключительно для клиента. Если вы также хотите настроить сервер, ему нужны собственные файлы хранилища ключей и доверенных сертификатов. На этом веб-сайте можно найти отличное руководство по настройке полностью работающего примера для клиента и сервера Java (с использованием Tomcat) .
Проблемы / Замечания / Советы
- Аутентификация сертификата клиента может быть применена только сервером.
- ( Важно! ) Когда сервер запрашивает сертификат клиента (как часть рукопожатия TLS), он также предоставляет список доверенных CA как часть запроса сертификата. Когда сертификат клиента, который вы хотите представить для аутентификации, не подписан ни одним из этих ЦС, он вообще не будет представлен (на мой взгляд, это странное поведение, но я уверен, что для этого есть причина). Это было основной причиной моих проблем, поскольку другая сторона не настроила свой сервер должным образом для принятия моего самозаверяющего клиентского сертификата, и мы предположили, что проблема была в моем конце в том, что я не правильно предоставил клиентский сертификат в запросе.
- Получить Wireshark. Он имеет отличный анализ пакетов SSL / HTTPS и будет очень полезен при отладке и поиске проблемы. Это похоже на,
-Djavax.net.debug=ssl
но является более структурированным и (возможно) более легким для интерпретации, если вас не устраивает отладочный вывод Java SSL.
Вполне возможно использовать библиотеку Apache httpclient. Если вы хотите использовать httpclient, просто замените целевой URL-адрес на HTTPS-эквивалент и добавьте следующие аргументы JVM (которые одинаковы для любого другого клиента, независимо от библиотеки, которую вы хотите использовать для отправки / получения данных по HTTP / HTTPS) :
-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStoreType=pkcs12
-Djavax.net.ssl.keyStore=client.p12
-Djavax.net.ssl.keyStorePassword=whatever
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.trustStore=client-truststore.jks
-Djavax.net.ssl.trustStorePassword=whatever