В предыдущей статье обсуждались вопросы безопасности Web-сервисов в приложениях, применяемых в электронной коммерции по схеме B2B. В ней также были упомянуты XML-стандарты безопасности, разрабатываемые международными организациями W3C и OASIS.
В этой статье рассматриваются три XML-стандарта безопасности: "Подпись XML" (XML Signatures), "Шифрование XML" (XML Encryption) и "Безопасность Web-сервисов" (Web Services Security) - которые регламентируют следующую функциональность при передаче SOAP-сообщений: пользовательскую аутентификацию, целостность сообщений и конфиденциальность. Можно быть уверенным, что эти три спецификации "заткнут дыру" в SOAP-сервере, о которой рассказывалось в предыдущей статье. А в следующей статье на примере создания, обмена и обработки XML-сообщений в брандмауэрах XML будет показано, как "заделывается эта дыра".
Основные понятия криптографии
При обсуждении целостности сообщений, аутентификации пользователей и конфиденциальности используются некоторые базовые понятия: ключи, криптография, подписи и сертификаты. Ниже кратко изложены основы криптографии. За более подробной информацией обращайтесь в раздел Ресурсы, где содержится ссылка на справочник по криптографии, который можно бесплатно скачать.
Асимметричная криптография
Распространенная криптографическая методика состоит в применении пары ключей: открытого и закрытого. Сначала используется подходящий криптографический алгоритм генерации пары открытый-закрытый ключ. Открытый ключ может быть открыт для использования любому лицу, с которым необходимо установить безопасную передачу сообщений. Закрытый ключ держится в секрете и никому не открывается. Открытый ключ применяется для шифрования сообщений, а соответствующий закрытый ключ для их расшифровки.
Для того, чтобы отправить конфиденциальное сообщение отправителю необходим открытый ключ. С его помощью это сообщение шифруется, а затем отсылается. Получатель этого сообщения расшифровывает его с помощью закрытого ключа. В этом случае никто, кроме владельца закрытого ключа, не может дешифровать сообщение. Такая технология известна как асимметричное шифрование. Пары открытых-закрытых ключей также иногда называют асимметричными ключами.
Симметричная криптография
Существует еще один метод криптографии - так называемая симметричная криптография. При симметричной криптографии для шифрования и дешифрования используется один и тот же ключ. В этом случае этот секретный ключ - симметричный ключ - является общим для двух участников обмена сообщениями. С точки зрения вычислений симметричная криптография требует меньше затрат по сравнению с асимметричной. Именно поэтому асимметричная криптография обычно применяется только для передачи общей конфиденциальной информации. Как только обменивающиеся сообщениями стороны ее получают, они могут перейти к использованию симметричной криптографии.
Дайджесты сообщений
Дайджесты сообщений - это еще одно понятие, которым оперируют при защищенной передаче сообщений по Интернет. Алгоритмы дайджестов схожи с хэш-функциями: они читают ("переваривают") данные для вычисления значения хеш-функции, называемого дайджестом сообщения. Дайджест сообщения зависит от данных и алгоритма дайджеста. Значение дайджеста может использоваться для проверки целостности сообщения; то есть для обеспечения неизменности данных во время их передачи отправителем получателю. Отправитель посылает дайджест сообщения вместе с этим сообщением. По получении сообщения получатель заново производит вычисление дайджеста . Если в сообщение были внесены изменения, это значение будет другим, и это будет свидетельствовать о том, что сообщение было изменено.
Однако, что делать, если и сообщение, и дайджест изменены? Такой тип модификаций невозможно установить на стороне получателя. Поэтому одних алгоритмов дайджестов сообщения недостаточно для обеспечения целостности сообщений - для решения указанной проблемы необходимы цифровые подписи.
Цифровые подписи
Ключи также используются для создания и проверки цифровых подписей. Алгоритм дайджеста можно применять для вычисления значения дайджеста сообщения, а затем с помощью закрытого ключа по этому значению сгенерировать цифровую подпись. Получатель этого сообщения сначала проверит целостность значения хэш-функции, повторив вычисление дайджеста. Затем он использует открытый ключ отправителя сообщения для проверки подписи. Если значение дайджеста было изменено, эта подпись не будет подтверждена на стороне получателя. Если же проверка значения дайджеста и подписи приведет к положительному результату, можно сделать следующий вывод:
- после вычисления дайджеста в сообщение не вносились изменения (целостность сообщения); и
- сообщение получено действительно от владельца открытого ключа (пользовательская аутентификация).
Сертификаты
В самом общем виде цифровые сертификаты - это структура данных, которая содержит две информационных части:
- идентификацию (например, имя, контактный адрес и пр.) владельца сертификата (индивидуума или организации); иоткрытый ключ владельца сертификата.
- открытый ключ владельца сертификата.
Сертификаты, которые издают соответствующие органы, предоставляются отдельным лицам или организациям и включают две необходимых части : личность владельца и открытый ключ. Такие органы также подписывают сертификат, используя свой собственный закрытый ключ - любая заинтересованная сторона может убедиться в целостности сертификата, проверив эту подпись.
Обеспечение целостности данных и пользовательской аутентификации с помощью подписей XML:
Спецификация подписи XML - "Цифровая подпись XML" (XMLDS) - которая была разработана совместными усилиями организации W3C и IETF, имеет статус Рекомендации W3C. Этот документ определяет правила обработки и синтаксис, предназначенные для упаковки в XML-формат данных о целостности сообщения, его аутентификации и пользовательской аутентификации.
Вернемся к примеру из предыдущей статьи - в нем речь шла о взаимодействии между туроператором и его партнерами (отелями). Предположим, что туроператор хочет вызвать метод GetSpecialDiscountedBookingForPartners Web-сервиса своего партнера. Этот метод предоставляет услугу интерактивного резервирования мест в отеле по специальной цене (со скидкой). Причем увидеть эту скидку могут только бизнес партнеры, а не потребители.
Вызывая метод SOAP GetSpecialDiscountedBookingForPartners, туроператор включает в него информацию о целостности сообщения и пользовательской аутентификации. При получении этого вызова брандмауэру XML отеля потребуется просмотреть SOAP-сообщение, чтобы поверить, что:
- сообщение не было изменено, пока оно передавалось в Web-сервис отеля (целостность сообщения); и
- запрашивающая сторона является бизнес партнером (пользовательская аутентификация).
Если выполнены эти два условия, брандмауэр XML разрешает запрашивающей стороне перейти к SOAP-серверу. На рисунке 1 показ процесс пользовательской аутентификации:
- Туроператор направляет в Web-сервис отеля SOAP-запрос о вызове метода. Этот запрос включает всю информацию, относящуюся к обеспечению безопасности (пользовательская аутентификация и пользовательская аутентификация).
- Web-сервис отеля защищен брандмауэром XML, который принимает все запросы, направляемые в этот SOAP-сервер. брандмауэр XML проверяет, идентично ли полученное сообщение тому, которое запрашивающая сторона собиралась отправить.
- Если целостность сообщения не нарушена, брандмауэр XML считывает идентификационную информацию запрашивающей стороны из этого SOAP-запроса и проверяет, является ли этот пользователь бизнес партнером.
- Если запрашивающая сторона является бизнес партнером, брандмауэр XML разрешает запрашивающей стороне перейти к SOAP-серверу.
Рис. 1. Процесс пользовательской аутентификации с использованием брандмауэра XML
Листинг 1 - это простой SOAP-запрос, который передает в Web-сервис отеля вызов метода GetSpecialDiscountedBookingForPartners. В этом SOAP-запросе отсутствуют какие-либо данные о целостности сообщения или пользовательской аутентификации. Листинг 1 - это начальная точка демонстрации применения спецификации "Цифровая подпись XML".
Листинг 1
<?xml version=”1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”>
<SOAP-ENV:Body>
<s:GetSpecialDiscountedBookingForPartners
xmlns:s=“http://www.MyHotel.com/partnerservice/”>
<!--Parameters passed with the method call-->
</s:GetSpecialDiscountedBookingForPartners>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP в данном случае используется как пример XML-формата, чтобы продемонстрировать "Цифровую подпись XML", которая не является специфичной для SOAP. Поэтому ее можно применять, чтобы вставлять подписи и профили сообщения в любой экземпляр XML: SOAP или какой-либо иной.
В следующем примере теги цифровой подписи XML будут вставлены в заголовок SOAP. Цифровая подпись - это гибкая технология, она допускает включение таких тегов в любое место XML-файла. На самом деле существуют три типа подписей XML: заключающая в конверт (enveloping), заключаемая в конверт (enveloped) и обособленная (detached). Если подпись XML оборачивает данные, подлежащие подписанию, говорят, что это заключающая в конверт подпись. Если же данные, подлежащие подписанию, оборачивают эту подпись (например, подпись XML становится элементом данных XML, которые подписываются), то эта подпись называется заключаемой в конверт. Наконец, если подпись и данные, подлежащие подписанию, хранятся раздельно - подписываемый элемент и элемент подписи являются элементами одного уровня - такую подпись принято считать обособленной. В примере, который в этой статье иллюстрирует применение спецификации "Цифровая подпись XML", используются обособленные подписи.
Формирование цифровой подписи XML: основные четыре шага
Первый шаг - это создание элемента Signature. Со временем этот элемент будет оборачивать все другие элементы цифровой подписи XML. У Листинга 2 точно такое же тело как и у Листинга 1, единственное отличие между ними заключается в том, что Листинг 2 содержит объявление пространства имен цифровой подписи XML (http://www.w3.org/2000/09/xmldsig#) и заголовок SOAP. Этот заголовок SOAP оборачивает элемент Signature.
Листинг 2
<?xml version=”1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>
<SOAP-ENV:Header>
<ds:Signature>
<ds:SignedInfo>
</ds:SignedInfo>
<ds:SignatureValue>
</ds:SignatureValue>
<ds:KeyInfo>
</ds:KeyInfo>
</ds:Signature>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<s:GetSpecialDiscountedBookingForPartners
xmlns:s=“http://www.MyHotel.com/partnerservice/”>
<!--Parameters passed with the method call-->
</s:GetSpecialDiscountedBookingForPartners>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Элемент Signature в Листинге 2 содержит три дочерних элемента: SignedInfo, SignatureValue и KeyInfo.
Этот элемент является единственным обертывающим элементом для других тегов цифровой подписи XML. В последующих шагах: 2, 3 и 4 - мы создадим дочерние узлы для этих трех потомков Signature (SignedInfo, SignatureValue и KeyInfo).
Второй шаг - создание дочерних узлов элемента SignedInfo. Листинг 3 - результат включения дочерних узлов SignedInfo в Листинг 2. Законченная структура элемента SignedInfo - подробная иллюстрация того, как создается подпись XML - элемент SignedInfo имеет несколько потомков, каждый из которых содержит несколько бит информации, назначение которой будет раскрыто ниже.
Листинг 3
<?xml version=”1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>
<SOAP-ENV:Header>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#GetSpecialDiscountedBookingForPartners">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>
BIUddkjKKo2...
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
</ds:SignatureValue>
<ds:KeyInfo>
</ds:KeyInfo>
</ds:Signature>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<s:GetSpecialDiscountedBookingForPartners
xmlns:s=“http://www.MyHotel.com/partnerservice/”
ID="GetSpecialDiscountedBookingForPartners">
<!--Parameters passed with the method call-->
</s:GetSpecialDiscountedBookingForPartners>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
CanonicalizationMethod - это обязательный элемент, который идентифицирует алгоритм канонизации, применяемой к элементу SignedInfo до создания подписи.
Алгоритмы канонизации чрезвычайно важны при подписании XML, поскольку алгоритмы дайджестов сообщений интерпретируют XML как поток двоичных данных. Два различных потока могут представлять один и тот же ресурс. Например, если изменить последовательность атрибутов в элементе XML, результирующий XML-файл является логически эквивалентной версией исходного XML-файла. Однако, эти два логически эквивалентных файла будут содержат разные потоки данных и создают различные дайджесты.
Алгоритмы канонизации предназначены для генерации двоичных потоков для логически эквивалентных данных XML. Чтобы быть уверенным, что логически эквивалентные XML-документы создают один и тот же дайджест (и одинаковую подпись), необходимо канонизировать ресурс XML до создания дайджеста потока данных.
Элемент CanonicalizationMethod в Листинге 3 содержит атрибут Algorithm, значением которого является строка URI (http://www.w3.org/2001/10/xml-exc-c14n#). Эта строка URI указывает алгоритм, описанный спецификацией W3C - "Исключительная канонизация XML" (Exclusive XML Canonicalization). Подробности канонизации XML выходят за рамки этой статьи. Детальная информация о канонизации может быть найдена в статьях, ссылки на которые приведены в разделе Ресурсы.
На данном этапе просто создается элемент CanonicalizationMethod - а алгоритм канонизации пока не используется. Он будет применяется к элементу SignedInfo после того, как будут сформированы все его потомки.
Следующий потомок элемента SignedInfo - это элемент SignatureMethod, атрибут Algorithm которого указывает алгоритм, используемый для создания криптографической подписи.
Третий потомок элемента SignedInfo - элемент Reference. У элемента SignedInfo должен быть хотя бы один элемент Reference. Этот элемент используется для хранения информации, которая включает:
- Указание данных, которые подлежат подписанию. Для этого используется атрибут URI элемента Reference. Подписываемые данные могут быть как внутри XML-документа, так и вне него. Если данные и подпись находятся в одном и том же XML-документе, для их указания используется идентификатор фрагмента в виде значения атрибута URI элемента Reference. Так, в Листинге 3 значение атрибута URI указывает на элемент GetSpecialDiscountedBookingForPartners. Если же данные являются внешними по отношению к файлу с цифровой подписью XML, ссылаться на них необходимо посредством URI как значения атрибута URI элемента Reference.
Цифровая подпись XML позволяет выполнять ряд операций над данными прежде, чем профилировать и подписывать их. Например, до того, как подписывать данные, их можно канонизировать, или до их профилирования к ним можно применить какие-либо преобразования XSL. Так, если данные о ценах представлены в табличной форме, их можно преобразовать, получив обычный счет-фактуру. Для этого можно воспользоваться преобразованием XSL как шаблоном этого счета. Это означает, что будет подписываться весь счет, а не только необработанные данные, включенные в файл с цифровой подписью XML.
Элемент Transforms содержит информацию о том, какие операции выполняются на данных до их подписания. У элемента Transforms в Листинге 3 имеется один дочерний элемент Transform. Таких элементов может быть любое количество.
Каждый элемент Transform указывает алгоритм преобразования. Если преобразовывать данные до их подписания, необходимо включить указание о том, что было сделано, добавив элемент Transform. Благодаря этому получатель подписанного файла сможет выполнить такое же преобразование до того, как попытаться проверить подпись. В нашем примере была выполнена только одна операция - алгоритм канонизации, указанный посредством атрибута Algorithm элемента Transform.
В том случае если элемент Transforms содержит более одного элемента Transform, необходимо учитывать их порядок следования. Преобразования выполняются в том порядке, в каком они появляются в элементе Transforms. Все они производятся до профилирования данных. Следовательно, выходные данные последнего элемента Transform являются входными данными для алгоритма профиля сообщения.
- Алгоритм, используемый для создания дайджеста. Спецификация "Цифровая подпись XML" рекомендует использовать алгоритм профиля SHA-1. Эта информация находится в элементе DigestMethod, потомке элемента Reference - в значении его атрибута Algorithm (http://www.w3.org/2000/09/xmldsig#sha1).
- Значение дайджеста. Элемент DigestValue в Листинге 3 содержит действительное значение дайджеста, полученное применением алгоритма дайджеста к канонической форме элемента GetSpecialDiscountedBookingForPartners. Необходимо отметить, что бинарные данные в необработанном виде (такие как поток, созданный алгоритмами дайджеста сообщения, подписи и шифрования) не могут быть завернуты в разметку XML - это может осложнить разбор XML. Прежде чем оборачивать их в разметку XML, такие данные представляются в кодировке base-64. В результате, зашифрованные данные не содержат битов, которые могли бы конфликтовать с правилам обработки XML.
После того, как SignedInfo и его дочерние элементы сформированы, необходимо провести канонизацию всего элемента SignedInfo по алгоритму, указанному в элементе CanonicalizationMethod. После этого следует получить значение дайджеста и обернуть это значение в элемент SignatureValue, как показано в Листинге 4. Во время подписания каноническая форма элемента SignedInfo используется в качестве данных, подлежащих подписанию. В нее входят все дочерние элементы элемента SignedInfo.
Листинг 4
<?xml version=”1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>
<SOAP-ENV:Header>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#GetSpecialDiscountedBookingForPartners">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>
BIUddkjKKo2...
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
halHJghyf765....
</ds:SignatureValue>
<ds:KeyInfo>
</ds:KeyInfo>
</ds:Signature>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<s:GetSpecialDiscountedBookingForPartners
xmlns:s=“http://www.MyHotel.com/partnerservice/”
ID="GetSpecialDiscountedBookingForPartners">
<!--Parameters passed with the method call-->
</s:GetSpecialDiscountedBookingForPartners>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Необходимо отметить, что структура SignedInfo содержит ссылку на подписываемые данные (атрибут URI элемента Reference), значение дайджеста и имя метода подписи, а также другие биты информации. Следовательно, подписание структуры SignedInfo фактически означает подписание дайджеста данных вместе с самой ссылкой на эти данные.
В Листинге 2 у элемента Signature есть еще один дочерний элемент по имени KeyInfo. Четвертый шаг - создание его потомков. В Листинге 5 элемент KeyInfo содержит дочерний элемент KeyName. Этот элемент KeyName является идентификатором ключа, который используется для проверки подписи. KeyName - это просто "заполнитель" для идентификаторов ключа. Спецификация "Цифровая подпись XML" не определяет механизм, который соотносит идентификатор с действительной парой ключей, используемых для подписания. Проектирование механизма идентификации ключа - задача приложений, реализующих "Цифровую подпись XML". Например, идентификатор ключа в Листинге 5 (MyKeyIdentifier) может идентифицировать общий секретный ключ (симметричный ключ), которым уже обменивались туроператор и отель.
Листинг 5
<?xml version=”1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”
xmlns:ds=”http://www.w3.org/2000/09/xmldsig#”>
<SOAP-ENV:Header>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#GetSpecialDiscountedBookingForPartners">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>
BIUddkjKKo2...
</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
halHJghyf765....
</ds:SignatureValue>
<ds:KeyInfo>
<ds:KeyName>MyKeyIdentifier</ds:KeyName>
</ds:KeyInfo>
</ds:Signature>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<s:GetSpecialDiscountedBookingForPartners
xmlns:s=“http://www.MyHotel.com/partnerservice/”
ID="GetSpecialDiscountedBookingForPartners">
<!--Parameters passed with the method call-->
</s:GetSpecialDiscountedBookingForPartners>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Кроме того, элемент KeyInfo - необязательный: его можно как включать, так и не включать в подпись. Этот элемент является необязательным, потому что при подписании, возможно, может не потребоваться включать информацию о ключе в файл с цифровой подписью XML. Элемент KeyInfo может также использоваться при шифровании XML, о чем будет рассказано в следующем разделе.
Эти четыре шага - простая демонстрация применения спецификации "Цифровая подпись XML". Листинг 5 - полное SOAP-сообщение, которое в своем заголовке несет данные о целостности сообщения и пользовательской аутентификации.
Рассмотрим, как обрабатывается заголовок сообщения, представленного в Листинге 5, на стороне Web-сервиса отеля.
Проверка цифровой подписи XML
Процедура проверки проста и логически может быть выведена из методики формирования цифровой подписи XML, рассмотренной выше. Она распадается на три этапа.
Во-первых, необходимо канонизировать элемент SignedInfo. Напомним, что элемент CanonicalizationMethod устанавливает алгоритм канонизации. Поэтому следует воспользоваться этой канонической формой элемента SignedInfo для оставшейся части процесса проверки.
Во-вторых, необходимо проконтролировать целостность сообщения, проверив дайджест, который находится в элементе Reference, сформированном ранее, на шаге 2. При проверке дайджеста нужно располагать информацией, которая включает:
- Данные, по которым построен дайджест. Следует разыменовывать атрибут Reference элемента, чтобы получить эти данные.
- Любые трансформации, которые могут применяться к этим данным до запуска алгоритма профиля. В элементе Transforms содержится эта информация. Прежде чем получать дайджест данных, необходимо применить к ним те же трансформации.
- Алгоритм дайджеста. Эта информация находится в значении атрибута Algorithm элемента DigestMethod. Необходимо применить этот дайджест сообщения и проверить, не отличается ли значение дайджеста от той, что содержится в элементе DigestValue.
Если проверка дайджеста приводит к отрицательному результату, то процесс проверки заканчивается и считается неудовлетворительным.
Если выясняется, что с величиной профиля все в порядке, наступает очередь третьего этапа - проверки подписи. Для проверки подписи необходим ключ подписавшей стороны (открытый или общий секретный). Информацию о ключе можно получить из элемента KeyInfo, если он присутствует (или если приложению уже известна такая информация). Как только ключ, используемый при проверке подписи, известен, нужно прочитать метод подписи, который применялся при создании этой подписи. Атрибут Algorithm элемента SignatureMethod содержит эту информацию. После чего следует воспользоваться канонической формой элемента SignedInfo и ключом, чтобы подтвердить величину подписи.
При реализации спецификации "Цифровая подпись XML" можно создавать заголовки SOAP для генерации подписанных SOAP-сообщений. Брандмауэр XML, находящийся на стороне получателя, обрабатывает этот заголовок SOAP, чтобы проверить подписи прежде чем переслать запрос на SOAP-сервер. Данный процесс представлен на рисунке 1. Задача обеспечения безопасности может быть достигнуты следующим образом:
- Можно проверить, что полученное SOAP-сообщение было действительно отправлено известным отправителем.
- Можно проверить, что полученные данные не были изменены, пока они передавались, и что они не отличаются от тех, что отправитель собирался отправить.
Таким образом, касаясь нашего примера, можно быть уверенным, что запрос о резервировании по специальной цене со скидкой был оправлен действительно партнером, и что эти данные не были изменены, пока они передавались. Тем не менее, возможно ситуация, когда данные, передаваемые по Интернет, могут быть просмотрены хакерами. Рассмотрим, как эта проблема может быть решена с помощью спецификации "Шифрование XML".
Шифрование XML
Спецификация шифрования XML удовлетворяет требованиям конфиденциальности XML-сообщений. Эта спецификация позволяет реализовать следующую функциональность:
- шифрование целого XML-файла;
- шифрование любого отдельного элемента XML-файла;
- шифрование только содержания XML-файла;
- шифрование данных, отличных от XML (например, рисунка JPG);
- шифрование уже зашифрованного элемента ("супершифрование").
Шифрование целого XML-файла
Давайте начнем с шифрования целого XML-файла. Листинг 6 - это пример такого зашифрованного файла. При этом исходный XML-документ не показан, поскольку он не нужен, так как шифрование XML-файла своим результатом имеет такую же XML-структуру - за исключением зашифрованной величины, заключенной в элементе CipherValue.
Листинг 6
<?xml version='1.0'?>
<EncryptedData
xmlns="http://www.w3.org/2001/04/xmlenc#"
MimeType="text/xml">
<EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>MyKeyIdentifier</ds:KeyName>
</ds:KeyInfo>
<CipherData>
<CipherValue>B457V645B45........</CipherValue>
</CipherData>
</EncryptedData>
Корневой элемент EncryptedData несет зашифрованные данные вместе с такой необходимой информацией, как алгоритм, используемый для шифрования. Этот элемент содержит объявление пространства имен шифрования XML (http://www.w3.org/2001/04/xmlenc#) и атрибут MimeType, значение которого равно text/xml. По этому атрибуту получатель этого зашифрованного XML-файла может понять, что XML-файл был зашифрован, чтобы создать структуру EncryptedData.
Первый потомок корневого элемента - элемент EncryptionMethod. Этот элемент содержит атрибут Algorithm, который определяет алгоритм, использованный при шифровании. Его значение равно http://www.w3.org/2001/04/xmlenc#3des-cbc, что определяет алгоритм тройной DES (Data Encryption Standard, Стандарт шифрования данных).
Элемент ds:KeyInfo тот же самый, что и тот, который использовался при применении спецификации "Цифровая подпись XML". Необходимо отметить, что этот элемент был позаимствован из пространства имен цифровой подписи XML.
Элемент EncryptedData содержит еще один дочерний элемент - CipherData, у которого в свою очередь имеется дочерний элемент CipherValue. Этот элемент CipherValue несет зашифрованное содержание (зашифрованную версию XML-документа). Таким образом, результатом шифрования XML-файла является содержание элемента CipherValue.
Шифрование отдельного элемента
Как было сказано выше, структура EncryptedData несет зашифрованные данные вместе с необходимой информацией. В основе шифрования одиночного элемента XML-файла лежит аналогичный подход. Рассмотрим Листинг 7, в котором зашифрованный элемент GetSpecialDiscountedBookingForPartners из Листинга 1 получен простой заменой элементом EncryptedData.
Листинг 7
<?xml version=”1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”>
<SOAP-ENV:Body>
<xenc:EncryptedData
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
Type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>MyKeyIdentifier</ds:KeyName>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>B457V645B45........</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Сравним элемент EncryptedData из Листинга 6 с элементом EncryptedData из Листинга 7. Нетрудно видеть, что имеется одно различие: вместо атрибута MimeType Листинга 6 в Листинге 7 появился атрибут Type. Значение этого атрибута равно http:///www.w3.org/2001/04/xmlenc#Element, что означает, что зашифрован XML-элемент.
Таким образом, при шифровании элемента XML-файла следует использовать идентификатор http:///www.w3.org/2001/04/xmlenc#Element в качестве значения атрибута Type. В этом случае получатель зашифрованного XML-файла будет знать, что зашифрованные данные должны интерпретироваться как XML-элемент в расшифрованной простой текстовой форме.
Шифрование содержания элемента
Рассмотрим Листинг 8, в котором зашифровано только содержание элемента GetSpecialDiscountedBookingForPartners - для этого это содержание было заменено структурой EncryptedData. Этот прием похож на шифрование элемента (см. Листинг 7). Отличие состоит в том, что на этот раз значение атрибута Type тега EncryptedData равно http://www.w3.org/2001/04/xmlenc#Content. Это значение говорит о том, что зашифрованные данные должны интерпретироваться как содержание элемента.
Листинг 8
<?xml version=”1.0”?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=”http://schemas.xmlsoap.org/soap/envelope/”>
<SOAP-ENV:Body>
<s:GetSpecialDiscountedBookingForPartners
xmlns:s=“http://www.MyHotel.com/partnerservice/”
ID="GetSpecialDiscountedBookingForPartners">
<xenc:EncryptedData
xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
Type="http://www.w3.org/2001/04/xmlenc#Content">
<xenc:EncryptionMethod
Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>MyKeyIdentifier</ds:KeyName>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>B457V645B45........</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</s:GetSpecialDiscountedBookingForPartners>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Обработка шифрования XML
Рассмотрим, как брандмауэр XML работает с понятиями шифрования. Брандмауэр получает Листинг 7 или 8 (SOAP-сообщения с зашифрованными элементами или содержанием) и, прежде чем переслать SOAP-серверу расшифрованный запрос SOAP-сообщения, преобразует их содержание в дешифрованную форму.
Получатель зашифрованного XML-файла (например, в нашем случае брандмауэр XML отеля) расшифровывает этот XML-файл, выполняя следующую последовательность действий:
- Извлекает зашифрованное содержание элемента CypherValue.
- Считывает значение атрибута алгоритма элемента EncryptionMethod.
- Считывает значение атрибута Type элемента EncryptedData.
- Получает информацию о ключе из элемента ds:KeyInfo.
- Использует полученную информацию для создания простого текстового (расшифрованного) файла.
Введение в безопасность Web-сервисов
Возникает вопрос, каким образом брандмауэр XML использует подписи и шифрование XML для защиты SOAP-серверов? Ведь несмотря на то, что возможности этих двух технологий были продемонстрированы на многочисленных примерах, необходимо выяснить, как применять эти две спецификации при использовании брандмауэра XML для защиты SOAP-серверов, особенно если учесть ни одна из них не является специфичной для SOAP. Попытаемся понять, почему вся информация, касающаяся подписи, была помещена в заголовок SOAP, а не в тело SOAP.
Спецификация консорциума OASIS "Безопасность Web-сервисов" подробно определяет, как применять технологии подписи и шифрования XML при обмене SOAP-сообщениями. Этот стандарт получает элементы низкого уровня из рассмотренных выше спецификаций ("Цифровая подпись XML" и "Шифрование XML") и задает высокоуровневый синтаксис для обертывания в SOAP-сообщениях информации о безопасности.
Спецификация "Безопасность Web-сервисов" описывает механизм безопасного обмена SOAP-сообщениями. Она обеспечивает следующую функциональность:
- Целостность сообщения.
- Пользовательскую аутентификацию.
- Конфиденциальность.
Рассмотрим Листинг 9 - это SOAP-сообщение, которое несет информацию о безопасности согласно синтаксису спецификации "Безопасность Web-сервисов". Листинг 9 - этот тот же самый SOAP-запрос GetSpecialDiscountedBookingForPartners, который неоднократно приводился в этой статье. Однако на этот раз заголовок запроса передает информацию о цифровой подписи в соответствии с рассматриваемой спецификацией.
Листинг 9
<?xml version="1.0" encoding="utf-8"?>
<SOAP:Envelope
xmlns:SOAP="http://www.w3.org/2001/12/soap-envelope"
xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/xx/secext"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<SOAP:Header>
<wsse:Security>
<wsse:BinarySecurityToken
ValueType="wsse:X509v3"
EncodingType="wsse:Base64Binary"
wsu:Id="MyTourOperatorCertificate">
LKSAJDFLKASJDlkjlkj243kj;lkjLKJ...
</wsse:BinarySecurityToken>
<ds:Signature>
<ds:SignedInfo>
<ds:CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml -exc-c14n# "/>
<ds:SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#myDiscountRequestBody">
<ds:Transforms>
<ds:Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>BSDFHJYK21f...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
GKLKAJFLASKJ52kjKJKLJ345KKKJ...
</ds:SignatureValue>
<ds:KeyInfo>
<wsse:SecurityTokenReference>
<wsse:Reference URI="#MyTourOperatorCertificate"/>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</SOAP:Header>
<SOAP-ENV:Body>
<s:GetSpecialDiscountedBookingForPartners
xmlns:s=“http://www.MyHotel.com/partnerservice/”
ID="myDiscountRequestBody">
<!--Parameters passed with the method call-->
</s:GetSpecialDiscountedBookingForPartners>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Чтобы лучше понять синтаксис спецификации "Безопасность Web-сервисов", рассмотрим Листинг 9:
- Элемент SOAP:Envelope содержит объявления пространств имен для SOAP, "Безопасность Web-сервисов" и "Цифровой подписи XML".
- У элемента SOAP:Header имеется только один дочерний элемент (wsse:Security), который является оберткой для всей информации о безопасности. У элемента wsse:Security два дочерних элемента: wsse:BinarySecurityToken и ds:Signature.
- Элемент wsse:BinarySecurityToken содержит маркер доступа (security token). Маркер доступа подобен пропуску, выдаваемому службой безопасности, или удостоверению личности, которое необходимо предъявить при входе в область ограниченного доступа. Ниже описаны основные типы маркеров доступа.
Наиболее популярный и широко используемый маркер доступа - это пара логин-пароль, как та, что применяется при проверке электронной почты.
Пара логин-пароль - это маркер доступа, предназначенный для человека. Существуют маркеры доступа, которые имеют бинарную форму (и, следовательно, могут быть нечитабельны). Такие маркеры называются бинарными маркерами доступа. Например, сертификат X509 (очень популярный формат цифровых сертификатов, разработанный Международным союзом электросвязи - сектора телекоммуникаций (International Telecommunications Union - Telecommunications sector, ITU-T)) - это бинарный маркер доступа.
Атрибут ValueType элемента wsse:BinarySecurityToken содержит информацию о том, какой тип бинарного маркера доступа завернут в элемент wsse:BinarySecurityToken. В Листинге 9 значение этого атрибута равно wsse:X509v3, что означает сертификат X509.
Атрибут EncodingType элемента wsse:BinarySecurityToken показывает, какая кодировка у бинарного маркера доступа. Как уже отмечалось выше, бинарные данные не могут быть завернуты в формат XML. Следовательно, они должны быть преобразованы в данный формат (как правило, они представляются в кодировке base-64). Сертификат X509 обернут в элемент wsse:BinarySecurityToken как содержание этого элемента.
- Элемент ds:Signature точно такой же как и тот, что был рассмотрен ранее в разделе о подписи XML. Необходимо обратить внимание на следующие два момента:
- Значение атрибута URI (#myDiscountRequestBody) элемента Reference является идентификатором фрагмента, который указывает на элемент SOAP:Body. Это означает, что элемент SOAP:Body - это тот элемент, который уже был подписан и обернут в теги цифровой подписи XML.
- У элемента ds:KeyInfo имеется элемент wsse:SecurityTokenReference, который содержит ссылки на маркеры доступа. В нашем случае у него есть дочерний элемент wsse:Reference, атрибут URI которого указывает на элемент wsse:BinarySecurityToken, рассмотренный в пункте 3 этого раздела. Это означает, что открытый ключ в сертификате X509 (то, что оборачивает элемент wsse:BinarySecurityToken) используется для проверки подписи.
Рассмотренный пример очень прост, он знакомит с подписанными сообщениями защищенных Web-сервисов. В третьей и четвертой статьях этого цикла будут подробно рассмотрены вопросы безопасности XML: различные типы маркеров доступа, которые могут использоваться с "Безопасностью Web-сервисов", и случае применения спецификации "Шифрование XML" в сообщениях защищенных Web-сервисов.
В следующей статье будет представлен Язык разметки утверждений безопасности (Security Assertions Markup Language, SAML), который позволяет приложениям Web-сервисов совместно использовать информацию о пользовательской аутентификации. Этот обмен аутентификационными данными обычно называется одиночным предъявлением пароля (single sign-on). SAML может быть использован как маркер доступа в приложениях защищенных Web-сервисов. В следующей статье будет объяснено почему, когда и как.
Ресурсы
- Официальные страницы рабочих групп W3C Подпись XML (XML Signature) и Шифрование XML (XML Encryption).
- Страница "Безопасность Web-сервисов" рабочей группы OASIS.
- Цикл статьей (Часть 1 и Часть 2), посвященных канонизации XML.
- В данном справочнике приводится подробное объяснение криптографии. В ней рассмотрены ключи, шифрование, цифровые подписи и профили сообщений.
- Эта статья знакомит с сертификатами X.509.