Платформа цифрового подписывания соглашений об открытой упаковке

 

Дэвид Мельцер и Андрей Шур
Microsoft Corporation

Сентябрь 2006 г.

Область применения:
   OPC Digital Signing Framework
   Стандарт цифровой подписи W3C XML
   Microsoft .NET 3.0 Framework

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

Содержимое

Введение
Компоненты платформы цифровой подписи OPC
   Стандарт цифровой подписи XML
   Представление цифровых подписей в пакетах
   Подписывание частей и связей
Поддержка программирования для подписей пакетов
   Подписывание частей и связей пакета
   Проверка сертификатов и подписей
Политика подписывания приложений
   XPS-документы
   Поддержка программирования для подписей XPS
Ссылки

Введение

Модель упаковки, указанная в Open Packaging Conventions (OPC), описывает пакеты, части и связи. Пакеты содержат части, которые содержат содержимое и ресурсы. Связи определяются для соединения пакета с частями, а также для соединения различных частей пакета.

В этой статье рассматривается платформа цифровой подписи OPC, приводятся общие сведения о компонентах пакета и вспомогательных службах, а также примеры политики подписывания и ее реализации.

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

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

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

В этой статье предполагается, что вы знакомы со спецификацией открытых соглашений об упаковке и синтаксисом и обработкой xml-подписи рекомендации W3C.

Компоненты платформы цифровой подписи OPC

Стандарт цифровой подписи XML

Платформа подписывания для пакетов использует стандарт цифровой подписи XML, как определено в рекомендации W3C синтаксис и обработка XML-подписи. В этой рекомендации указаны синтаксис XML и правила обработки для создания и хранения цифровых подписей.

Стандарт определяет тип элемента XML-подписи, схему и требования к соответствию для подписывания и проверки любого вида цифрового ресурса. Схема также определяет элементы для ссылок на ресурсы и указания алгоритмов, связанных с сигнатурами.

Возможности цифровых подписей

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

Цифровая подпись также может использоваться для идентификации подписывателя содержимого. Удостоверение подписывателя представлено сертификатом, связанным с подписью. Сертификат может быть внедрен в подпись или доступен в другом месте.

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

Представление цифровых подписей в пакетах

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

Платформа подписывания использует элементы и атрибуты из пространства имен упаковки, где это разрешено стандартом цифровой подписи XML. Элементы сигнатуры, определенные в пространстве имен упаковки, поддерживают функции, относящиеся к пакету, которые дополняют стандарт, не противоречат ему. Сводные сведения о дополнениях см. в разделе "Изменения в спецификации цифровой подписи XML" спецификации OPC.

Части пакета, определенные для платформы подписывания, являются частью Origin, частью XML-подписи и частью certificate. Каждый имеет четко определенный тип контента. Четко определенные типы связей используются для соединения частей подписи в пакете, как указано в приложении H "Стандартные пространства имен и типы контента" спецификации OPC.

Часть источника цифровой подписи

Часть "Источник цифровой подписи" является отправной точкой для навигации по подписям в пакете. Часть "Источник цифровой подписи" ориентирована из корневого каталога пакета с помощью связи "Источник цифровой подписи ". Несколько частей сигнатуры могут быть нацелены на часть Origin. Если в пакете нет подписей, часть Origin не будет присутствовать.

Часть XML-подписи цифровой подписи

Части xml-подписи цифровой подписи содержат разметку, определенную в стандарте цифровой подписи W3C, а также в пространстве имен упаковки. Эти части предназначены для xml части источника цифровой подписи с отношением "Цифровая подпись ".

Часть сертификата цифровой подписи

Сертификат X.509, необходимый для идентификации подписывающего, если он помещается в пакет, может быть внедрен в часть XML-подписи или храниться в отдельной части сертификата. Необязательная часть certificate (Сертификат) используется для части XML-подписи с отношением сертификата цифровой подписи . Часть "Сертификат" может совместно использоваться несколькими частями подписи.

Настраиваемые части подписи

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

Подписывание частей и связей

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

Тип контента части подписывается вместе с содержимым части, чтобы гарантировать, что часть в действительно подписанном пакете будет использоваться или отображаться по назначению. Так как тип контента не является адресуемым ресурсом, для подписывания значения типа контента применяется подход, зависящий от пакета. Когда пакет подписан, тип контента каждой подписанной части сохраняется в компоненте запроса URI, ссылающегося на подписанную часть. При использовании пакета платформа цифровой подписи OPC использует значение типа контента, чтобы убедиться, что тип контента части не изменился с момента подписания части.

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

Преобразование связей создает часть связей, содержащую только указанный набор связей. Полученная часть связей используется для подписывания и проверки подписи.

Поддержка программирования для подписей пакетов

Для подписывания и проверки подписей приложения могут использовать классы .NET 3.0 PackageDigitalSignatureManager. Зависящие от пакета классы, определенные в пространстве имен System.IO.Packaging , создаются на основе классов цифровой подписи Платформы Microsoft .NET 3.0, определенной в пространстве имен System.Security.Cryptography.Xml .

Класс PackageDigitalSignatureManager используется для создания и проверки подписей, а также для размещения инфраструктуры подписей в пакете. Сигнатура представлена объектом на основе класса PackageDigitalSignature .

Подписывание частей и связей пакета

Приложение определяет список частей и связей для подписывания в соответствии с политикой подписывания. Затем приложение вызывает метод PackageDigitalSignatureManager.Sign() для создания подписи и добавления инфраструктуры подписей в пакет.

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

Начало процесса подписывания

Чтобы начать работу с сигнатурами в пакете, сначала создайте PackageDigitalSignatureManager, как показано ниже.

    // Open the package.
    Package package = Package.Open(filename);

    // Create the PackageDigitalSignatureManager
      PackageDigitalSignatureManager dsm =
        new PackageDigitalSignatureManager(package);

Параметры внедрения сертификата

Сертификат может быть представлен как строка, внедренная в саму сигнатуру, как отдельная часть пакета или как ресурс за пределами пакета. Если сертификат должен быть помещен в пакет, приложение указывает, как сертификат будет сохранен с помощью параметров внедрения свойства PackageDigitalSignature.CertificateOption . После создания класса PackageDigitalSignatureManager задаются параметры внедрения для сертификата, как показано в примере кода ниже.

    //Specify that the certificate is embedded in the signature held
    //in the XML Signature part.

    //Certificate embedding options include:
    // InSignaturePart – Certificate is embedded in the signature.
    // InCertificatePart – Certificate is embedded in a 
    //                     separate certificate part

    dsm.CertificateOption =
        CertificateEmbeddingOption.InSignaturePart;

Список подписанных частей

Список подписываемых частей указывается с помощью универсальных кодов ресурса (URI), адресуемых к частям. В этом примере подписываются все части пакета, за исключением частей связей, которые отфильтровываются с помощью метода PackUriHelper.IsRelationshipPartUri().

    //Initialize a list to hold the part URIs to sign.

    System.Collections.Generic.List<Uri> partsToSign =
        new System.Collections.Generic.List<Uri>();

    //Add each part to the list, except relationships parts.
    foreach (PackagePart packagePart in package.GetParts())
    {
        if (!PackUriHelper.IsRelationshipPartUri(packagePart.Uri))
      partsToSign.Add(packagePart.Uri);
  }

Список подписанных связей

Отдельные связи подписываются с помощью преобразования связей. Подписывание связей таким образом позволяет добавлять новые связи в пакет без аннулирования подписи.

Связи выбираются для подписывания путем создания списка объектов PackageRelationshipSelector , которые будут использоваться во время подписи. Объекты PackageRelationshipSelector можно создавать как группу по типу связи (как определено в разделе "Стандартные пространства имен и типы контента" открытого соглашения об упаковке) или создаваться по отдельности путем указания идентификатора связи, как показано в примере ниже.

     //Create list of selectors for the list of relationships

     List<PackageRelationshipSelector> relationshipSelectors = 
          new List<PackageRelationshipSelector>();

     //Create one selector for each package-level relationship, based on id

  foreach (PackageRelationship relationship in package.GetRelationships())
            {
                relationshipSelectors.Add(new
                    PackageRelationshipSelector(relationship.sourceUri, 
                    PackageRelationshipSelectorType.Id, relationship.Id));
            }

При создании PackageRelationshipSelector с PackageRelationshipSelectorType.Id для подписывания будет выбрана одна связь с указанным уникальным идентификатором. При создании селектора с помощью PackageRelationshipSelectorType.Type для подписи выбираются все связи с указанным типом. Если в пакет позже добавляются связи одного типа, подпись будет признана недействительной.

Создание объекта certificate

Перед подписанием действительный сертификат X.509 получается путем создания экземпляра объекта типа System.Security.Cryptography.X509Certificates.X509Certificate2. Этот объект передается методу PackageDigitalSignatureManager.Sign() во время подписывания. Дополнительные сведения о создании объектов сертификатов см. в разделе Пространство имен System.Security.Cryptography.X509Certificates .

Применение подписи

После создания списка частей и связей для подписывания и получения объекта сертификата приложение вызывает метод PackageDigitalSignatureManager.Sign().

     //Sign package using components created above

     PackageDigitalSignature signature = dsm.Sign(partsToSign, 
          x509Certificate, relationshipSelectors);

     //After signing, close the package.
     //The signature will be persisted in the package.
     package.Close();

При вызове метода Sign() хэш создается и сохраняется в манифесте сигнатуры, а также создается часть подписи. Если инфраструктура подписей уже существует в пакете, будет добавлена новая часть подписи (если это разрешено). Если инфраструктура еще не существует в пакете, метод Sign() создает инфраструктуру и помещает ее в пакет.

Проверка сертификатов и подписей

Приложения могут проверять сертификат или подпись. Перед проверкой подписи необходимо проверить сертификат. Объект, представляющий подпись в пакете PackageDigitalSignature, имеет свойство Signer, которое возвращает сертификат, используемый для создания этой подписи, если он находится в пакете. Если сертификат не внедрен в пакет, приложение получает сертификат из расположения, известного приложению.

Метод PackageDigitalSignatureManager.VerifyCertificate() используется для проверки полученного сертификата, проверки структуры сертификата, даты окончания срока действия и состояния цепочки. Дополнительные сведения о состоянии цепочки см. в разделе Перечисление X509ChainStatusFlag в библиотеке классов платформа .NET Framework.

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

Метод PackageDigitalSignatureManager.VerifySignatures() используется для проверки всех подписей в пакете. Этот метод проверяет только подписи, но не сертификаты, связанные с подписями.

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

    // Open the package.

    Package package = Package.Open(filename);

    // Create the PackageDigitalSignatureManager

    PackageDigitalSignatureManager dsm =
        new PackageDigitalSignatureManager(package);

    // Verify the collection of certificates in the package (one, in this case)

        foreach(PackageDigitalSignature signature in pdsm.Signatures)
        {
        if(PackageDigitalSignatureManager.VerifyCertificate(signature.Signer)
            != X509ChainStatusFlags.NoError)
              {
                // Application-specific code for error handling 
                // or certificate validation 
              }
        }
 
   // For this example, if all certificates are valid,
   // verify all signatures in the package.
 
    VerifyResult vResult = dsm.VerifySignatures(false);
    Console.WriteLine("Result " + vResult.ToString());

    // Close the package.

    package.Close();

Политика подписывания приложений

Приложения, использующие форматы на основе пакетов, определяют собственные политики в рамках платформы подписывания. Политика определяется типами элементов и требованиями к рабочему процессу формата. В этом разделе описана политика подписывания для одного формата на основе пакета Майкрософт: формата XPS-документа.

XPS-документы

Формат документа XPS основан на соглашениях об открытой упаковке, как указано в спецификации xml paper. Спецификация XML-бумаги определяет политику для подписывания документов XPS. В этой политике доступны параметры подписывания для поддержки функций приложения или рабочего процесса.

Политика подписывания для пакетов документов XPS

Политика подписывания для документов XPS описывает набор частей и связей, которые должны быть подписаны для проверки содержимого. В рамках этой политики приложение может создать сигнатуру, которая при необходимости включает комбинацию определенных частей, которые примечаются к содержимому, например часть CoreProperties. Подписывание этих частей не позволит изменить их без отмены подписи. Кроме того, приложения могут при необходимости подписывать часть связей, присоединенную к части "Источник цифровой подписи" в подписи, запрещая добавлять новые подписи в документ без аннулирования подписи.

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

Подписываемые части документа XPS

В следующей таблице содержится список частей, которые должны быть подписаны во всех документах XPS, и частей, которые при необходимости подписываются. Для связей политика подписывания XPS указывает, что необходимые связи (связи, предназначенные для обязательных частей) всегда подписываются с помощью преобразования связей, определяемого OPC. Если часть подписана, также должны быть подписаны отношения, предназначенные для нее.

Тип части Политика
Часть FixedDocumentSequence Должен быть подписан
Часть FixedDocument Должен быть подписан
Части DocumentStructure Должен быть подписан
Часть SignatureDefinitions Должен быть подписан
Части FixedPage Должен быть подписан
Обязательные части ресурсов (например, шрифты, изображения) Должен быть подписан
Части StoryFragments Должен быть подписан
Части эскизов Должен быть подписан
Часть CoreProperties Подпись (необязательно)
Часть источника цифровой подписи Подпись (необязательно)
Часть сертификата цифровой подписи Подпись (необязательно)
Части PrintTicket Подпись (необязательно)
Части DiscardControl Подпись (необязательно)

Дополнительные сведения о политике подписывания XPS см. в разделе "Функции пакета документов XPS: цифровые подписи: правила подписывания" в спецификации XML-бумаги.

Политика подписывания совместимости разметки

В спецификации XML-документа описывается способ включения альтернативного содержимого в ДОКУМЕНТ XPS: совместимость разметки. Альтернативное содержимое помещается в элементы из пространства имен совместимости разметки. По политике документы XPS с элементами и атрибутами совместимости разметки не могут быть подписаны правильно, если приложение подписывания не распознает все альтернативы содержимого как эквивалентные. Подписывание или проверка могут быть только документы XPS, содержащие элементы и атрибуты, которые распознаются.

Скрепляющая подпись

К содержимому документа XPS можно применить несколько подписей. Например, содержимое, представляющее юридический контракт, может потребовать, чтобы несколько человек применили свои подписи, указывая на подписанное содержимое и удостоверение подписывателя.

Добавление новой сигнатуры всегда создает новую связь в части связей, присоединенной к части "Источник цифровой подписи". Чтобы добавить новые подписи в документ XPS без отмены существующих подписей, эта часть связей должна оставаться без подписи (хотя подмножество связей может быть подписано). Если часть связей включена в сигнатуру, эта подпись будет признана недействительной всеми последующими примененными подписями.

Проверка подписей XPS

Помимо определения создания подписи, политика подписывания XPS также определяет, как проверить подпись как действительную. Политика определяет состояния допустимости для подписи, включая несовместимые, неработающие, сомнительные и допустимые, как показано в следующей таблице.

Состояние подписи Все обязательные части и связи подписаны? Подпись включает только распознанное содержимое? Хэш подписанного содержимого проверен? Распознано ли содержимое совместимости подписанных исправлений? Сертификат действителен?
Несоответствующий NO

YES

Недоступно

NO

Недоступно

Недоступно

Недоступно

Недоступно

Недоступно

Недоступно

Неисправно YES YES NO Недоступно Недоступно
Сомнительной YES

YES

YES

YES

YES

YES

NO

YES

Недоступно

NO

Допустимо YES YES YES YES YES

В средстве просмотра XPS отображаются сомнительные и неработаемые подписи XPS, а также допустимые подписи XPS. Несовместимые сигнатуры не перечисляются.

Поддержка программирования для подписей XPS

При работе с документом XPS приложения могут использовать методы класса XpsDigitalSignature . Этот класс основан на классе PackageDigitalSignature и включает методы, которые соответствуют алгоритмам и требованиям, указанным в спецификации цифровой подписи XPS. Методы подписывания и проверки проверяют, подписаны ли все необходимые части и связи документа XPS.

Подписывание документа XPS

Метод XpsDocument.SignDigitally() используется для подписи документа XPS. Перед вызовом метода приложение должно иметь сертификат X.509, который можно получить с помощью объекта System.Security.Cryptography.X509Certificates.X509Certificate2.

     // Open the XPS Document

     XpsDocument document = new XpsDocument(dstContainer,
          FileAccess.ReadWrite);

     // Obtain the certificate object from a file

     X509Certificate certificate =
          509Certificate.CreateFromCertFile(certFilename);

     // Create the signature and add it to the document using
     // the OPC Signing Framework

     document.SignDigitally(certificate, true, 
          XpsDigSigPartAlteringRestrictions.None);

XpsDigSigPartAlteringRestrictions можно использовать для указания дополнительных ограничений для подписи на основе политики подписи. Этот параметр указывает, следует ли исключать из сигнатуры части CoreMetadata и (или ) SignatureOrigin . Исключенные части можно изменить позже, не принося сигнатуру. Например, исключение части CoreMetadata из сигнатуры позволяет приложению изменять некоторые свойства документа без отмены подписи.

Части PrintTicket и DiscardControl исключаются из сигнатур, созданных методом SignDigitally(), хотя эти части при необходимости могут быть подписаны определенным для приложения способом.

Проверка подписи документа XPS

Одна или несколько подписей могут храниться в документе XPS. Подписи можно получить из свойства XpsDocument.Signatures . Каждая сигнатура представлена экземпляром объекта XpsDigitalSignature .

В приведенном ниже примере проверяется только первая подпись в коллекции.

     // Open the XPS Document.

     // Obtain the first enumerated signature.

     foreach (XpsDigitalSignature digitalSignature in
              document.Signatures)
     { 
          // Verify the signature object, if present.

          if (digitalSignature.Verify() ==
     System.IO.Packaging.PackageDigitalSignature.VerifyResult.Success)
          {
         //Signature is valid
          }
     }

Ссылки