Взаимная аутентификация с веб-сервисами

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

Прежде всего есть ли какие-либо ресурсы, которые кто-либо знает этого, может помочь мне с этим? Я искал некоторое время и ничего не нашел. Какие-либо другие подсказки, которые кто-либо может дать мне о том, как пойти об этом?

Во-вторых, я думаю, что мой самый большой контрольно-пропускной пункт является моим отсутствием понимания того, как обработать сертификаты. Как я согласовываю принятие ключа сервера и представление моего собственного ключа к серверу? Это находится в Java.

22
задан jww 5 May 2016 в 06:07
поделиться

4 ответа

Если библиотека веб-службы использует стандартный класс java.net.URL в качестве HTTP-клиента, можно задать некоторые системные свойства, и двусторонняя аутентификация будет обрабатываться встроенной поддержкой HTTPS.

The necessary properties are:

  • javax.net.ssl.trustStore: Содержит сертификаты корневого ЦС
  • javax.net.ssl.keyStore: Содержит сертификат клиента и закрытый ключ
  • javax.net.ssl.keyStorePassword: Пароль, защищающий закрытый ключ клиента

Эти настройки становятся значениями по умолчанию для всех SSL-соединений процесса. Если вы хотите более тонкого контроля, вам придется настроить свой собственный SSLContext. Возможно ли это с вашей средой выполнения веб-сервиса, зависит от того, какую среду выполнения вы выбрали.

6
ответ дан 29 November 2019 в 05:07
поделиться

Простой рецепт приведен в этой записи блога .

Но я думаю, что реальный ответ может зависеть от того, какие Java API вы используете для реализации HTTP-взаимодействия на стороне клиента. Например, похоже, что вы сделали бы что-то немного по-другому , используя JAX-RPC.

1
ответ дан 29 November 2019 в 05:07
поделиться

Для взаимной аутентификации с помощью SSL (также известного как двусторонний SSL) вне браузера вам понадобится ... Ну, на самом деле, давайте сначала посмотрим, что вам нужно для одностороннего SSL:

  1. Хранилище ключей сервера
  2. Клиентское хранилище доверенных сертификатов

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

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

Таким образом, вы можете реализовать односторонний SSL (традиционный вариант использования).

Чтобы реализовать двусторонний SSL, вам нужно сделать эту настройку «симметричной», поэтому нам нужно будет добавить:

  1. Склад ключей клиента
  2. Склад доверенных сертификатов сервера

Склад ключей клиента содержит клиентские (возможно, самоподписанный) сертификат и закрытый ключ. Это хранилище используется клиентом для тех же целей, что и хранилище ключей сервера, то есть для отправки учетных данных клиента на сервер во время рукопожатия взаимной аутентификации TLS.

Склад доверенных сертификатов сервера содержит клиентские (самозаверяющие) автономные сертификаты (извлеченные из клиентского хранилища ключей в отдельные сертификаты без личного ключа клиента). Это требуется по точно таким же причинам, как упоминалось ранее.

Некоторые ресурсы, которые помогут вам создать все это и реализовать окончательные решения:

13
ответ дан 29 November 2019 в 05:07
поделиться

Я потратил на это много времени, но наконец нашел пример, который действительно работает. Он основан на Glassfish и Netbeans, но я думаю, что вы могли бы заставить его работать в других средах (например, Eclipse и Tomcat), если вы поиграете с ним.

http://java.sun.com/webservices/reference/tutorials/wsit/doc/WSIT_Security9.html#wp162511

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

Примечание: я не эксперт по безопасности. Не развертывайте это в производственной среде!

Для этого я использую NetBeans 6.9, JDK 1.6, GlassFish 3.0.1 и OpenSSL v1.0 (я использую неофициальные двоичные файлы Win32)

# Create the CA
mkdir ca server client
cd ca
openssl req -new -x509 -days 3650 -extensions v3_ca -keyout ca.key -out ca.pem
echo 02 > serial.txt
cd ..

# Creating the Server Keystore

openssl req -days 3650 -newkey rsa:1024 -keyout server/server.key -out server/server.req
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in server/server.req -out server/server.crt
openssl pkcs12 -export -inkey server/server.key -in server/server.crt -out server/server.p12 -name server
keytool -importkeystore -destkeystore server/server.jks -deststoretype jks -srckeystore server/server.p12 -srcstoretype pkcs12
keytool -exportcert -alias server -keystore server/server.jks -file server/server.cer

# Create the Client Keystore

openssl req -days 3650 -newkey rsa:1024 -keyout client/client1.key -out client/client1.req
openssl x509 -extensions usr_cert -extfile C:\testbed\OpenSSL-Win32\bin\openssl.cfg -CA ca/ca.pem -CAkey ca/ca.key -CAserial ca/serial.txt -req -in client/client1.req -out client/client1.crt
openssl pkcs12 -export -inkey client/client1.key -in client/client1.crt -out client/client1.p12 -name client1
keytool -importkeystore -destkeystore client/client1.jks -deststoretype jks -srckeystore client/client1.p12 -srcstoretype pkcs12
keytool -exportcert -alias client1 -keystore client/client1.jks -file client/client1.cer

# Import public keys and certificates into each others keystores

keytool -import -noprompt -trustcacerts -alias client1 -file client/client1.cer -keystore server/server.jks
keytool -import -noprompt -trustcacerts -alias server -file server/server.cer -keystore client/client1.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore server/server.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore client/client1.jks
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\cacerts.jks"
keytool -import -noprompt -trustcacerts -alias my_ca -file ca/ca.pem -keystore "C:\Program Files\Java\jdk1.6\jre\lib\security\cacerts"
move "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks" "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks.backup"
copy server\server.jks "C:\Program Files\glassfish-3.0.1\glassfish\domains\domain1\config\keystore.jks"

В консоли администратора GlassFish включите Security на вашем http-listener, установите флажки SSL3, TLS и Client Authentication, установите Certificate NickName на server, Key Store на config\keystore. jks, Trust Store - config\keystore.jks, Trust Algorithm - PKIX и оставьте Max Certificate Length равным 5.

В NetBeans создайте новый проект Web Application. В нем создайте новую веб-службу.

Код моей веб-службы выглядел следующим образом:

@WebService()
public class ListProducts {

  @Resource WebServiceContext context;

  @WebMethod(operationName = "listProducts")
  public String listProducts() {
    return context.getUserPrincipal().toString();
  }

}

Щелкните правой кнопкой мыши на веб-службе и выберите Edit Web Service Attributes. Поставьте галочку в поле Secure Service и выберите Mutual Certificates Security в качестве механизма безопасности. Нажмите на кнопку Configure... и отметьте поле Encrypt Signature. Теперь снимите флажок Use Development Defaults и нажмите кнопку Keystore. Установите расположение вашего хранилища ключей server.jks и выберите псевдоним server. Сделайте то же самое для конфигурации Truststore (хотя здесь не нужно выбирать псевдоним).

Импортируйте клиентский сертификат client1.p12 в браузер. Разверните веб-службу на Glassfish. Откройте веб-службу в браузере и перейдите к развернутому WSDL по HTTPS. Загрузите WSDL и любые другие схемы. Переименуйте все ссылающиеся схемы в локальные копии, чтобы при использовании WSDL2Java NetBeans не использовал удаленные ресурсы. (Этот пункт связан с тем, что вы ограничили WSDL клиентами с одобренным сертификатом, но NetBeans не может получить его удаленно, потому что у него нет доступа к данному сертификату).

Создайте новый проект Java. Создайте новый клиент веб-службы. Когда появится запрос, укажите NetBeans на сохраненный WSDL-файл. Импортируйте файлы библиотеки METRO2.0 (C:\Program Files\Netbeans 6.9\enterprise\modules\ext\metr\webservices-*.jar). Мой код выглядел так:

public static void main(String[] args) {
  System.getProperties().put("javax.net.ssl.keyStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks");
  System.getProperties().put("javax.net.ssl.keyStorePassword", "changeit");
  System.getProperties().put("javax.net.ssl.trustStore", "C:\\NetBeansProjects\\security-04\\ssl\\client\\client1.jks");
  System.getProperties().put("javax.net.ssl.trustStorePassword", "changeit");
  System.out.println(new ListProductsService().getListProductsPort().listProducts());
}

Скопируйте webservices-api.jar в каталог Java\jdk1.6\jre\lib\endorsed. Щелкните правой кнопкой мыши на ссылке Web Service и выберите Edit Web Service Attributes. Установите расположение хранилища ключей на client1.jks и задайте псевдоним client1. Установите расположение хранилища truststore в client1.jks и задайте псевдоним server.

Надеюсь, теперь вы можете запустить свой клиент, и вы должны увидеть следующие результаты: EMAILADDRESS=bob@anonymous.org, CN=Bob Smith, OU=Something, O=SomethingElse, L=AnyTown, ST=AnyState, C=US

14
ответ дан 29 November 2019 в 05:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: