---
title: "Подпись XML-документов несколькими ЭЦП"
description: "Краткая заметка, пока не забыл. Возник вопрос о подписании XML-документов несколькими ЭЦП, и соответ..."
author: "vovan_sidorytch"
published: "2010-10-20T03:56:45+00:00"
modified: "2010-10-20T03:56:45+00:00"
locale: "ru"
canonical_url: "https://yvision.kz/post/podpis-xml-dokumentov-neskolkimi-ecp-80990"
markdown_url: "https://yvision.kz/post/podpis-xml-dokumentov-neskolkimi-ecp-80990/markdown"
site_name: "Yvision.kz"
---

# Подпись XML-документов несколькими ЭЦП

> Краткая заметка, пока не забыл. Возник вопрос о подписании XML-документов несколькими ЭЦП, и соответ...

Краткая заметка, пока не забыл. Возник вопрос о подписании XML-документов несколькими ЭЦП, и соответственно проверка соответствия содержимого с подписями. Технологии работы с XML-подписями не новы сами по себе, в Гугле легко найти немало информации по ним, не буду повторять общедоступные в сети факты. Но вот что касается неоднократного подписания одного XML-документа, информации намного меньше, она более разрознена и менее подробна (ну или я недостаточно хорошо искал).

Есть три основных алгоритма подписания:
- **detached** - подпись хранится отдельно от структуры подписываемого документа

- **enveloping** - подписываемые данные находятся внутри XML-структуры, описывающей подпись

- **enveloped** - XML-структура, описывающая подпись, добавляется внутрь подписываемых данных

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

У меня уже был готовый код подписания и проверки подписи XML-документов, использующий стандартные библиотеки языка (Java, но это не важно, т.к. стандарт XML не зависит от программных реализаций). Оказалось, что принципы установки подписи, при множественном подписании остались теми же, и их доработка не потребовалась. Для добавления последующих подписей следовало использовать повторно тот же функционал, что использовался ранее для установки единичной подписи, за счёт чего в структуру добавлялись новые элементы **Signature**.

Что же касается проверки валидности подписанного документа, возникли трудности - существующий функционал сообщал о несоответствии подписи содержимому документа, в случае, если количество подписей превышало 1. Немного исследований выяснили следующее: существующий функционал находил в XML-документе первую подпись и пытался сверить данные с ней. Как оказалось, первая подпись была неверна потому, что после её добавления в документ, сам документ изменялся - в него добавлялись ещё подписи. Общий механизм примерно следующий: первая подпись удостоверяет непосредственно данные документа; вторая подпись удостоверяет данные документа, подписанные первой подписью, т.е. подписывается сам документ и первая подпись; соответственно третья подпись удостоверяет данные документа и первые две подписи и т.д. (напоминаю, что описывается алгоритм **enveloped**). При этом каждая последующая подпись делает невалидной предыдущую, т.к. изменяет структуру подписанного XML-документа. Возникает вопрос - как же в таком случае осуществлять проверку подписей, ведь если нельзя проверить ВСЕ подписи, зачем их вообще ставить в таком количестве? Ответ на самом деле не так уж и сложен - следует осуществлять последовательную сверку подписей, **начиная с последней**. При этом, после проверки каждой наиболее "внешней" подписи, её следует удалять из структуры документа, перед переходом к проверке следующей (с конца списка) подписи. Т.е., если у документа, например, 3 подписи, сначала сверяем третью, удаляем её из документа, сверяем вторую, удаляем, и наконец сверяем последнюю оставшуюся - то бишь первую. С учётом того, что современные программные средства создают из исходного XML-текста некоторую объектную структуру (обычно, соответствующую DOM - Document Object Model), такие манипуляции выполняются очень просто и не затрагивают к тому же исходный текст.

Такой подход, на мой взгляд, не очень красив, и в основном обусловлен выбором алгоритма - для подобных случаев, возможно, лучше подошёл бы алгоритм **detached**. Хотя, на самом деле они оба подходят в зависимости от бизнес-логики процесса подписания. Алгоритм **detached**, более применим в случаях когда не имеет значения очередность добавления разных подписей (например, при подписании документа сотрудниками, равными по рангу). В свою очередь **enveloped** описывает иерархическое подписание, когда очередная подпись ставится только при наличии предыдущей (например, когда директор подписывает только при наличии подписи начальника отдела).

Совсем кратко так и не получилось...

---

Source: [https://yvision.kz/post/podpis-xml-dokumentov-neskolkimi-ecp-80990](https://yvision.kz/post/podpis-xml-dokumentov-neskolkimi-ecp-80990)