gpt4 book ai didi

winapi - 如何验证我的组织是否签署了受信任的 Windows 二进制文件?

转载 作者:行者123 更新时间:2023-12-02 14:33:45 26 4
gpt4 key购买 nike

这是 question 1072540, 'WinVerifyTrust to check for a specific signature?' 的后续问题.

我想编写一个 C++ 函数,我们将其命名为 TrustedByUs,其形式为:

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

我们的想法是,我们为该函数提供一个指向已使用数字签名签名的二进制 .dll 或 .exe 文件的路径。 pathToPublicKey 字符串是我们特定签名证书的公钥的路径。

使用http://support.microsoft.com/kb/323809中的代码验证 pathToBinary 文件实际上是否受到操作系统的信任非常简单。

现在我与问题 1072540 的作者处于同一位置,我知道操作系统信任该二进制文件的签名者,但我想知道我的组织的 RSA key 是否是签署该二进制文件的 key 。

KB323809 展示了如何从嵌入在我们的二进制文件中的证书中提取字符串。此示例展示了如何在其 GetProgAndPublisherInfo 函数中从签名证书中提取字符串,但我对使用字符串匹配来验证证书感到不舒服。

我想做的是从嵌入的签名中提取公钥,并将其与最初签署我的二进制文件的私钥对应的公钥进行比较。

CryptMsgGetParam 的文档表示 CMSG_SIGNER_CERT_ID_PARAM参数“返回识别签名者公钥所需的消息签名者信息”。我成功地用这个 key 获取了证书的序列号。我的代码如下所示:

// 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发现的证书信息,我应该使用什么技术来确保目标文件实际上是使用对应的私钥进行签名的执行上述代码时我可以使用的公钥?

最佳答案

您需要使用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

关于winapi - 如何验证我的组织是否签署了受信任的 Windows 二进制文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2008519/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com