Статьи

WS-Security: использование BinarySecurityToken для аутентификации

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

Большинство фреймворков, таких как WSS4J, по умолчанию будут подписывать только тело. Если вы добавляете дополнительные заголовки, такие как заголовок Timestamp, вам нужно будет явно указать их подпись. Используя поддержку Spring для WSS4J, например, вы можете установить разделенный запятыми список, содержащий имя локального элемента и соответствующее пространство имен, используя свойство securementSignatureParts .

Ниже приведен пример, как дать ему команду подписать элемент Body и Timestamp (и их родные элементы). Это приведет к добавлению двух цифровых подписей к сообщению:

1
2
</property>

В конце концов сообщение SOAP будет отправлено вместе с данными цифровой подписи XML и в большинстве случаев с BinarySecurityToken, содержащим сертификат. Пока ничего нового. Однако, что поразило меня, так это то, что кажется, что не совсем понятно, какова цель BST, и как контролируется аутентификация с ее использованием. Позвольте мне попытаться пролить некоторый свет на это: сертификат отправителя, который отправляется вместе с сообщением SOAP, играет роль идентификации. Вы можете сравнить его как имя пользователя ++. Должно быть ясно, что сертификат внутри сообщения не может быть доверенным, равно как и имя пользователя без проверки пароля. Пока что все согласны с этим: «Да, конечно, сертификаты должны быть проверены, чтобы быть доверенными, и тогда все готово!» Но это еще не все. Проверка сертификата не совпадает с проверкой подлинности. Тот факт, что сертификат в сообщении является действительным и подписан известным ЦС, недостаточно для того, чтобы считать отправителя аутентифицированным. Например: я в самый злой час мог перехватить сообщение, изменить содержимое, создать новую подпись на основе моего личного ключа и заменить BST в сообщении своим сертификатом. Мой сертификат может быть официальным сертификатом, подписанным ЦС (даже подписанным тем же ЦС, который вы используете), так что он пройдет проверку проверки. Если инфраструктура просто проверит сертификат внутри сообщения, у нас вообще не будет безопасности.

Примечание. Если вы вместо этого отправляете сообщение по защищенному транспорту, скорее всего, я не смог перехватить сообщение. Но безопасная транспортировка в основном прекращается до фактической конечной точки, оставляя небольшую часть транспорта «незащищенной». Хотя эта часть будет в основном внутри вашей компании, но я хочу отметить, что независимо от того, насколько безопасен ваш транспорт, конечная точка несет конечную ответственность за проверку личности отправителя. Например; в асинхронной системе сообщение SOAP могло быть помещено в очередь сообщений для последующей обработки. Когда обработка начинается конечной точкой, трассировка безопасного транспорта давно исчезла. Вам придется подтвердить личность, используя информацию, содержащуюся в сообщении.

Чтобы закрыть эту лазейку, у нас есть два решения: первое решение основывается на том, что мы уже описали: сертификат в сообщении проверяется на соответствие корневым сертификатам CA в доверенном хранилище. В этом сценарии рекомендуется сначала сузить набор доверенных ЦС. Например, вы можете договориться со своими клиентами об ограниченном списке CA, чтобы получить ваши сертификаты. Таким образом, вы уже снизили риск доверять более «серой зоне» ЦС, которые могут не придерживаться столь строгих правил выдачи сертификатов (как, например, правильная проверка личности своих клиентов). Во-вторых, поскольку * каждый * сертификат, выданный доверенным центром сертификации, будет считаться «аутентифицированным», мы закроем лазейку, выполнив некоторые дополнительные проверки. Используя WSS4J, вы можете настроить шаблон сопоставления на основе свойства DN субъекта сертификата. У них есть хорошая запись в блоге по этому вопросу здесь: http://coheigea.blogspot.ie/2012/08/subject-dn-certificate-constraint.html . Мы могли бы указать, что DN сертификата должно соответствовать заданному значению, как это:

1
2
Wss4jHandler handler = ...
handler.setOption(WSHandlerConstants.SIG_SUBJECT_CERT_CONSTRAINTS, "CN = ...");

Обратите внимание: в настоящее время в Wss4jSecurityInterceptor нет поддержки для этого с помощью поддержки Spring для WSS4J, поэтому вам придется расширить его, чтобы включить это!

Чтобы завершить выполняемые шаги:

  1. Сертификат, содержащийся в сообщении, проверен по доверенному центру сертификации в вашем доверенном лице. Когда эта проверка завершается успешно, она сообщает приложению, что сертификат все еще действителен и фактически был выдан центром сертификации, которому вы доверяете.
    • Эта проверка дает нам гарантию того, что сертификат действительно принадлежит той стороне, к которой он относится.
  2. При желании сертификат также можно проверить при отзыве, чтобы мы не продолжали доверять сертификатам, которые были явно отозваны.
  3. WSS4J проверит, соответствуют ли некоторые атрибуты сертификата требуемым значениям для конкретной службы (поддержка ограничения сертификата DN субъекта).
    • Это будет этап аутентификации; как только сертификат признан действительным, мы проверяем, является ли владелец сертификата тем, кому мы хотим предоставить доступ
  4. Наконец, подпись в сообщении проверяется путем создания нового дайджеста сообщения, сравнения его с расшифрованным дайджестом сообщения и т. Д.

Следует отметить, что эта проверка (по крайней мере, при использовании WSS4J) не выполняется по умолчанию! Если вы не укажете это и просто добавите свой CA в хранилище доверия, вы оставите дыру в безопасности!

Второе решение не требует дополнительной настройки и зависит только от сертификата отправителя, который должен присутствовать в хранилище доверенных сертификатов.
Сертификат, содержащийся в сообщении, сопоставляется с сертификатом в хранилище доверенных сертификатов. Если они совпадают, отправитель аутентифицируется. Нет необходимости проверять сертификаты в ЦС, поскольку сертификаты, импортированные в хранилище доверенных сертификатов, являются явно доверенными (WSS4J по-прежнему проверяет, не истек ли срок действия сертификата, и, возможно, проверяет его на отзыв). Опять же, в доверенном хранилище нет сертификатов CA (или промежуточных сертификатов CA)! Только сертификаты отправителей, которым вы хотите дать доступ тоже. Настоящим доступ контролируется путем добавления (или удаления) их сертификата из склада доверенных сертификатов.

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

Вывод

В предположении, что вы можете ограничить количество доверенных ЦС, первое решение в большинстве случаев является предпочтительным, а также наиболее масштабируемым. Для новых клиентов нет никаких изменений, необходимых для склада доверенных сертификатов. Соответствующие атрибуты могут храниться извне, поэтому их легко изменять / добавлять. Кроме того, когда срок действия клиентских сертификатов истекает или их аннулируют, вам не нужно делать ничего особенного. Новый сертификат будет использован отправителем в данный момент и будет напрямую проверен в ЦС в вашем доверенном хранилище. Во втором решении вам нужно будет добавить новый сертификат в trustore и оставить старый там некоторое время, пока не будет выполнено переключение.

В целом извлеченные уроки: водонепроницаемая безопасность трудна. Правило № 1 в ИТ (предположение является матерью всех неудач) здесь, безусловно, верно. Будьте скептичны и убедитесь, что вы полностью понимаете, что происходит. Никогда не доверяйте настройкам по умолчанию, пока вы не уверены, что они делают. Настройка по умолчанию для вашей домашней сигнализации (например, 123456) также не является хорошей идеей. Ни один из них не является паролем администратора по умолчанию при установке Tomcat.