Как проверить, что мой orgainization подписал доверяемый двоичный файл окон?

Это - последующий вопрос подвергнуть сомнению 1072540, 'WinVerifyTrust для проверки на определенную подпись?'.

Я хочу записать, что функция C++ Позволяет, называют его TrustedByUs из формы:

bool TrustedByUs(std::string pathToBinary, std::string pathToPublicKey)

Идея состоит в том, что мы даем этой функции путь к двоичному файлу .dll или .exe файлу, который был подписан с цифровой подписью. pathToPublicKey строка является путем к открытому ключу нашего конкретного сертификата подписания.

С помощью кода в http://support.microsoft.com/kb/323809 это является довольно прямым, чтобы проверить что pathToBinary файлу на самом деле доверяет операционная система.

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

KB323809 показывает, как извлечь строки из сертификата, встроенного в наш двоичный файл. Этот пример показывает, как извлечь строки из входящего в систему сертификата GetProgAndPublisherInfo функция, но я - неудобное использование строкового соответствия к verfiy сертификат.

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

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

// Get message handle and store handle from the signed file.
fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE,
    L"C:\\Program Files\\MySignedProgram.exe",
    CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
    CERT_QUERY_FORMAT_FLAG_BINARY,
    0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL);

// Get the public key information about the signer
// First get the size
DWORD dwCertIdSize(0);
fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_ID_PARAM,
    0, NULL, &dwCertIdSize);
BYTE* pCertId = new BYTE(dwCertIdSize);
::ZeroMemory(pCertId,dwCertIdSize);

// Now get the cert info
fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_ID_PARAM,
    0, (PVOID)pCertId, &dwCertIdSize);

if(fResult)
{      
    CERT_ID* pId = (CERT_ID*)pCertId;  
    pId->HashId;
    pId->dwIdChoice;
    pId->IssuerSerialNumber;  // Valid serial number (reversed)
    pId->KeyId;   
    _tprintf("pid\n");
}

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

Используя CMSG_ENCRYPTED_DIGEST флаг этот код успешно выполняется:

// Get digest which was encrypted with the private key
DWORD digestSize(0);
fResult = CryptMsgGetParam(hMsg, CMSG_ENCRYPTED_DIGEST, 0, NULL, &digestSize);

BYTE* pDigest = new BYTE[digestSize];

// Next CryptMsgGetParam call succeds,
// pDigest looks valid, can I use this to confirm my public key
// was used to sign MySignedProgram.exe ?
fResult = CryptMsgGetParam(hMsg, CMSG_ENCRYPTED_DIGEST, 0, pDigest, &digestSize);

Вопрос о нижней строке: Учитывая информацию о сертификате, обнаруженную CryptQueryObject, какая техника должна, я раньше удостоверялся, что конечный файл был на самом деле подписан с помощью закрытого ключа, который соответствует открытому ключу, который доступен мне, когда вышеупомянутый код выполняется?

9
задан StaceyGirl 9 April 2018 в 01:44
поделиться

1 ответ

Вместо этого вам нужен CMSG_SIGNER_INFO_PARAM.

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

CryptMsgGetParam(hMsg, 
                 CMSG_SIGNER_INFO_PARAM, 
                 0, 
                 NULL, 
                 &dwSignerInfo);
PCMSG_SIGNER_INFO pSignerInfo = (PCMSG_SIGNER_INFO) malloc(dwSignerInfo);
CryptMsgGetParam(hMsg, 
                 CMSG_SIGNER_INFO_PARAM, 
                 0, 
                 pSignerInfo, 
                 &dwSignerInfo);

PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hStore,
                                          ENCODING,
                                          0,
                                          CERT_FIND_SUBJECT_CERT,
                                          (PVOID)pSignerInfo,
                                          NULL);
// Compare with your certificate:
// - check pCertContext->pbCertEncoded (length is pCertContext->cbCertEncoded)

// *OR*
// Compare with your public-key:
// - check pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm and
//   pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey
7
ответ дан 4 December 2019 в 23:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: