Программно получить алгоритм дайджеста цифровой подписи для MSI-файлов в C ++ - PullRequest
2 голосов
/ 10 мая 2019

Я хочу получить алгоритм фактической подписи (а не алгоритм дайджеста сертификата), который использовался для подписи файла установщика Windows (msi).

Используя API шифрования Microsoft, я смог легко получить то, что хочу для exe.Сначала получая HCRYPTMSG, затем получая размер информации подписавшего, затем информацию подписывающего PCMSG_SIGNER_INFO и, наконец, получая сам алгоритм:

pSignerInfo-> HashAlgorithm.pszObjId

BOOL bIsOk;
DWORD dwEncoding=0, dwContentType = 0, dwFormatType = 0, dwSignerInfo = 0;
std::string szFileName= "pathtothefile";

//Get message handle and store handle from the signed file.
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
bIsOk = CryptQueryObject(CERT_QUERY_OBJECT_FILE, szFileName.c_str(), CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL,
    0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL);

По какой-то причине выполнение моего кода в файлах установщика msi всегда возвращает

CRYPT_E_NO_MATCH 0x80092009 Не удается найти запрошенный объект.

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

Мне интересно, не совместим ли API шифрования с файлами MSI для начала.

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

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 11 мая 2019

Ответ на вашу проблему находится в документации для CryptQueryObject :

CERT_QUERY_OBJECT_FILE: этот параметр является указателем на терминированный нулем Unicode строка, содержащая путь и имя файла для запроса.

Unicode в документации Windows означает UTF-16LE.Однако вы передаете std::string (используя char в качестве представления кодовой единицы).std::string (в Windows) кодируется с использованием ASCII или ANSI (кодировка кодовой страницы).Вам придется изменить это значение на std::wstring, которое использует wchar_t в качестве представления кодовой единицы:

std::wstring szFileName= L"pathtothefile";

wchar_t однозначно означает UTF-16LE в Windows.

0 голосов
/ 10 мая 2019

Юникод : Вам необходимо использовать строку Юникода для вызова (имя файла).


CString : в качестве быстрого теста я использовал стандартный CString в Visual Studio 2017 (Unicode). Пожалуйста, проверьте. Просто чтобы запустить его для дальнейшей отладки. Возможно, вы можете включить <atlstr.h>, если вы не включите CString уже.

//#include "atlstr.h"
BOOL bIsOk; DWORD dwEncoding = 0, dwContentType = 0, dwFormatType = 0, dwSignerInfo = 0;
CString test = "C:\\LibreOffice_6.2.3_Win_x64.msi";

<..>

bIsOk = CryptQueryObject(CERT_QUERY_OBJECT_FILE, test, CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL,
    0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL);

Ссылки

...