如何验证我的orgainization签署了一个可信的Windows二进制文件?

这是一个问题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
函数中从签名证书中提取字符串,但是使用字符串匹配来验证证书时我感到很不舒服。 我想要做的是从嵌入式签名中提取公钥,并将其与首先签署我的二进制文件的私钥对应的公钥进行比较。
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("pidn");
}
这接近我想要的,但实际上我想使用签名证书的公钥来验证目标签名二进制文件实际上是使用我的特定公钥/私钥对创建的。 使用
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
    

要回复问题请先登录注册