Поделиться через


Кодирование подписанных данных

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

На следующем рисунке показана процедура кодирования подписанного сообщения. Эти шаги описаны в списке, приведенном ниже.

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

кодирование подписанного сообщения

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

Кодирование подписанных данных

  1. Создаются данные (при необходимости) и извлекается указатель на него.
  2. Откроется хранилище сертификатов , содержащее сертификат подписывателя.
  3. Извлекается закрытый ключ для сертификата. Перед использованием сертификата необходимо задать два свойства. Один из них используется для привязки сертификата к определенному поставщику служб конфигурации, а в рамках этого CSP — к конкретному контейнеру закрытого ключа. Другой используется для указания того, какой алгоритм хэширования следует использовать при вызове хэш-операции . Их необходимо задать только один раз.
  4. Свойство сертификата определяет хэш-алгоритм.
  5. Хэш данных создается путем отправки данных через функцию хэширования.
  6. Подпись создается путем шифрования хэша с помощью закрытого ключа, полученного через свойство сертификата.
  7. В готовое подписанное сообщение включаются следующие данные:
    • Исходные данные для подписи
    • Хэш-алгоритмы
    • Подписи
    • Структуры сведений о подписывшем, включая идентификатор подписывателя (издатель сертификата и серийный номер).
    • Сертификаты подписывателя (необязательно)

Эта процедура иллюстрирует простой случай. Более сложные случаи включают в себя атрибуты, прошедшие проверку подлинности, включенные в сообщение. Если тип контента не является строкой BYTE или имеется по крайней мере один атрибут, прошедший проверку подлинности вместе с любым типом данных, требуются два стандартных атрибута: тип содержимого (данных) и хэш содержимого. В таких случаях CryptoAPI автоматически предоставляет эти два обязательных атрибута. Низкоуровневые функции сообщений хэшируют атрибуты, прошедшие проверку подлинности, шифруют хэш с помощью закрытого ключа и предоставляют его в качестве подписи.

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

Кодирование подписанного сообщения

  1. Создайте или получите содержимое.

  2. Получение поставщика служб шифрования.

  3. Получение сертификатов подписывателя.

  4. Инициализируйте структуру CMSG_SIGNER_ENCODE_INFO .

  5. Инициализируйте структуру CMSG_SIGNED_ENCODE_INFO .

  6. Вызовите CryptMsgCalculateEncodedLength , чтобы получить размер большого двоичного объекта закодированного сообщения. Выделите для него память.

  7. Вызовите CryptMsgOpenToEncode, передав CMSG_SIGNED для dwMsgType и указатель на CMSG_SIGNED_ENCODE_INFO для pvMsgEncodeInfo , чтобы получить дескриптор открытого сообщения.

  8. Вызовите CryptMsgUpdate, передав дескриптор, полученный на шаге 7, и указатель на данные, которые должны быть подписаны и закодированы. Эту функцию можно вызывать столько раз, сколько необходимо для завершения процесса кодирования.

  9. Вызовите CryptMsgGetParam, передав дескриптор, полученный на шаге 7, и соответствующие типы параметров для доступа к нужным закодированным данным. Например, передайте CMSG_CONTENT_PARAM, чтобы получить указатель на все сообщение PKCS 7 .

    Если результат этой кодировки будет использоваться в качестве внутренних данных для другого закодированного сообщения, например конвертированного сообщения, необходимо передать параметр CMSG_BARE_CONTENT_PARAM. Пример, демонстрирующий это, см. в разделе Альтернативный код для кодирования конвертированного сообщения.

  10. Закройте сообщение, вызвав CryptMsgClose.

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

Сведения о кодировании на языке C см. в разделе Пример программы C: подписывание, кодирование, декодирование и проверка сообщения.