Yvision.kz
kk
Разное
Разное
399 773 постов41 подписчиков
Всяко-разно
1
03:56, 20 октября 2010

Подпись 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 описывает иерархическое подписание, когда очередная подпись ставится только при наличии предыдущей (например, когда директор подписывает только при наличии подписи начальника отдела).

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

1
1376
2