1 | |
[Статья] Проверка электронной цифровой подписи Authenticode. Часть 2. Описание реализации11.05.2017, 02:05. Показов 4784. Ответов 3
Это продолжение. См. также другие части этой статьи:
Часть 1. Кусочек теории. Часть 3. Программа проверки Authenticode ЭЦП Часть 2. Описание реализации программы проверки подписей Содержание: 2.1. Подготовка к проверке 2.2. Запуск процедуры проверки и обработка результатов 2.3. Очистка ресурсов. 2.4. Извлечение сертификатов и содержащейся в них информации 2.5. Извлечение атрибутов и крос-подписей
0
|
11.05.2017, 02:05 | |
Ответы с готовыми решениями:
3
[Статья] Проверка электронной цифровой подписи Authenticode. Часть 1. Теория [Статья] Проверка электронной цифровой подписи Authenticode. Часть 3. Набор программ Проверка электронной цифровой подписи Постановка и проверка электронной цифровой подписи в Word Покупка цифровой подписи Authenticode (подпись софта) |
11.05.2017, 02:08 [ТС] | 2 | ||||||||||||||||||||||||||||||||||||||||
2.1. Подготовка к проверке
Замечу, что программа 32-битная, но полностью поддерживает проверку образов в 64-разрядных папках, так что далее по коду будут манипуляции с файловым переадресатором. Прототип функции проверки в модуле 'modDigiSign' выглядит таким образом:
DRIVER_ACTION_VERIFY – для проверки WHQL подписи драйвера. WINTRUST_ACTION_GENERIC_VERIFY_V2 – для проверки подписи остальных файлов. Примечание: сами провайдеры состоят из файлов библиотек и записей реестра:
Получая хендл к файлу, временно отключаем редиректор:
Получаем размер файла. Если он превышает MAX_FILE_SIZE (100 MB.) и не указан флаг игнорирования (SV_NoFileSizeLimit), выходим из программы. Лимит взят навскидку для защиты от подвисаний. Далее рассчитываем хеш файла:
Если файл был подписан через каталог, мы получим его контекст и затем можем запросить полный путь к файлу каталога безопасности (.cat) в структуру CATALOG_INFO:
Дальше мы заполняем структуры в зависимости от физического расположения подписи – внутренняя или внешняя (подписанная через каталог). Файл может быть подписан одновременно обеими. По-умолчанию, в этом случае проверяется подпись через каталог. Чтобы поменять приоритет, установите флаг SV_DisableCatalogVerify. Такой флаг устанавливается автоматически при проверке вторичной подписи через флаг SV_CheckSecondarySignature, т.к. вторичная подпись может быть только внутренней. Также, при проверке через каталог, не заполняется поле результатов проверки .isEmbedded. Чтобы принудительно заполнять это поле, укажите флаг SV_CheckEmbeddedPresence. Для проверки внутренней подписи нам нужно заполнить структуры: Возводим флаг: Для проверки внешней подписи заполняем структуры: 2.2. Запуск процедуры проверки и обработка результатов Проверка выполняется функцией WinVerifyTrust, экспортируемой WinTrust.dll, с передачей GUID провайдера политики проверки и указателя на WINTRUST_DATA. В этот момент файловый переадресатор должен быть отключён!
Возвращаемое значение – это результат проверки. Например, 0 – успешная проверка по всем политикам. Описание части других значений можно посмотреть, например, по ссылкам: MSDN. CERT_CHAIN_POLICY_STATUS structure MSDN. TRUST Error Codes На этом этапе программа преобразует код ошибки в описание (поля .ShortMessage и .FullMessage), заполняются поля .ReturnCode, .isLegit, .isSelfSigned, корректируется поле .isSigned, а также .isEmbedded (если было затребовано флагом SV_CheckEmbeddedPresence). В таком случае вызывается функция IsInternalSignPresent(), где в структуре PE проверяется наличие указателя на SecurityDir. Дополнительно в прокси-обработчик ошибок WriteError заложен случай проверки признака повреждения бинарных данных подписи. В результате проверки также заполняется структура WINTRUST_SIGNATURE_SETTINGS и поле WINTRUST_DATA -> hWVTStateData. hWVTStateData – содержит указатель на данные состояния проверки (см. далее в разделе 2.4.), по которым можно извлечь информацию о сертификатах и крос-подписях. Поле dwVerifiedSigIndex содержит индекс проверенной подписи. Поле dwIndex нужно заполнить другим индексом, если мы хотим проверить следующую подпись у файла. Такую проверку нельзя выполнить под этим же контекстом административного каталога (когда уже вызван WinVerifyTrust), поэтому для проверки вторичной подписи контекст нужно «перезагрузить», очистив ресурсы и получив новый контекст. Даже если указан флаг SV_CheckSecondarySignature, модуль modDigiSign всегда выполняет первый вызов WinVerifyTrust для получения кол-ва подписей и индекса первой из проверенных, чтобы узнать какой индекс у вторичной подписи для её последующей проверки. 2.3. Очистка ресурсов. Для освобождения ресурсов функцию WinVerifyTrust нужно вызвать повторно, заменив в поле dwStateAction флаг на WTD_STATEACTION_CLOSE. Контекст административного каталога освобождается функцией CryptCATAdminReleaseContext. Контекст каталога безопасности освобождается функцией CryptCATAdminReleaseCatalogContext. После чего закрывается хендл файла, а результат проверки сохраняется в локальный кеш. Если ваша программа больше не нуждается в проверке ЭЦП, разумно будет выполнить принудительную очистку памяти, занятой кешем. Для этого возведите флаг SV_CacheFree, передав пустое имя файла:
1
|
11.05.2017, 02:13 [ТС] | 3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2.4. Извлечение сертификатов и содержащейся в них информации
1. State data -> provider data.
В результате получаем данные о провайдере проверки (структура CRYPT_PROVIDER_DATA). 2. Provider data -> Provider signer
Кросс-подпись, например, может накладываться сервером отметки времени (см. раздел 2.5.). 3.1. Provider signer -> psSigner -> HashAlgorithm -> pszObjId
Прим.: чтобы получить алгоритма хеша подписи сертификата, с которым был подписан файл, см. пункт 5.2.1. Алгоритм помечен в виде идентификатора объекта (OID), список и расшифровку которых можно увидеть по ссылке: MSDN. CRYPT_ALGORITHM_IDENTIFIER structure. 3.2. Provider signer -> Provider cert.[]
Если Вам нужны сертификаты кросс-подписанта сделайте тоже самое над массивом CRYPT_PROVIDER_SGNR -> pasCounterSigners (см. раздел 2.5.). Он содержит указатели на другие CRYPT_PROVIDER_SGNR. 4. Provider cert -> Cert. context
Далее выполняю операции над двумя сертификатами: 1) корневым (сертификат центра сертификации):
1) CertGetCertificateContextProperty 2) CertNameToStr -> CertGetNameString Рассмотрим их: 5.1. Cert. context -> Property by ID
В данном случае я передаю CERT_HASH_PROP_ID, чтобы получить SHA256 хеш корневого сертификата. Также, этим способом я получаю e-mail адрес подписанта, т.к. функция имеет полезный флаг CERT_NAME_STR_ENABLE_PUNYCODE_FLAG для декодирования строк формата IA5_STRING, в котором может быть закодирована часть с хостом e-mail адреса. 5.2.1. Cert. context -> Cert. info
Теперь из нее мы можем получить алгоритм хеша подписи сертификата:
Ещё в этой структуре хранится такая полезная информация как: серийный номер сертификата, данные об издателе и подписанте, дата начала и дата истечения срока действия сертификата, публичный ключ и прочее. 5.2.2. Cert info subject (CRYPTOAPI_BLOB) -> Subject X.500 string
5.2.3. Subject X.500 string -> CN Извлекаем CN или по желанию другие параметры, с помощью ручного парсинга строки Distinguished Names (DN). Строка записана по стандарту rfc2253. Пример строки: Этим способом я получаю имя подписанта и имя организации, которая выдала сертификат. В завершение, контексты всех сертификатов освобождаются функцией CertFreeCertificateContext. Это нужно делать только с продублированным контекстом. 2.5. Извлечение атрибутов и крос-подписей Атрибуты являются частью цифровой подписи. Присутствие некоторых из них – опционально. Существует 2 вида атрибутов: – authenticated (удостоверенные, ещё называются – проверенные) – unauthenticated (неудостоверенные) Проверенные атрибуты – это часть данных, которые входят в выборку хеша и легитимность которых подтверждается в процессе проверки подписи. Неудостоверенные атрибуты не входят в выборку и их легитимность не подтверждается на первом этапе проверки основной подписи. Однако, существует такое понятие, как крос-подпись. Она накладывается поверх основной подписи. И храниться она как раз в виде неудостоверенного атрибута. Так что её легитимность проверяется отдельно, точно в таком же порядке, как и для основной подписи. Атрибут состоит из: – идентификатора атрибута (OID) – значения атрибута Неполный перечень атрибутов можно посмотреть в приложенном к статье файле OIDs.txt Так, в примере выше: Удостоверенные: 1.3.6.1.4.1.311.2.1.12 – это spcSpOpusInfo 1.2.840.113549.1.9.3 – это contentType (тип содержимого) 1.2.840.113549.1.9.4 – это messageDigest (выборка сообщения) Неудостоверенные: 1.3.6.1.4.1.311.3* – крос-подпись сервера штампа времени (подробнее о назначении см. раздел 1.3, п.3.) Рассмотрим пример с этой крос-подписью. Она также имеет собственные атрибуты: Посмотрим на OID 1.2.840.113549.1.9.5 (на рисунке уже расшифрован) – это время подписания файла. Значение любого атрибута кодируется в формате ASN.1, как:
Рассматриваемый OID представлен в стандарте RFC5652 (см. п.11.3). Его значение может быть закодировано в форматах: – UTCTime, как «YYMMDDHHMMSSZ» (для дат от 01.01.1950 до 31.12.2049) – GeneralizedTime, как «YYYYMMDDHHMMSSZ» (для всех остальных дат). При работе через CryptoAPI, это значение автоматически попадает в поле sftVerifyAsOf структуры CRYPT_PROVIDER_SGNR крос-подписи (в формате FILETIME с UTC+0). К этой крос-подписи может быть «прицеплена» ещё одна и так рекурсивно сколько угодно. Доступ к атрибутам из-под CryptoAPI можно получить через поля AuthAttrs и UnauthAttrs структуры CMSG_SIGNER_INFO, содержащие масив атрибутов CRYPT_ATTRIBUTE.
1
|
11.05.2017, 02:21 [ТС] | 4 |
0
|
11.05.2017, 02:21 | |
11.05.2017, 02:21 | |
Помогаю со студенческими работами здесь
4
Создание электронной цифровой подписи Считывание электронной цифровой подписи Алгоритм построения электронной цифровой подписи ЭльГамаля Удаление Электронной Цифровой Подписи(ЭЦП) с документов Excel Реализация электронной цифровой подписи на алгоритме гост 34.10.2012 Проверка электронной подписи Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |