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


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

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

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

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

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

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

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

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

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

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

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

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

  2. Получите криптографического поставщика.

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

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

  5. Инициализировать структуру CMSG_SIGNED_ENCODE_INFO.

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

  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.

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

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