Jak sprawdzić, czy moja organizacja podpisała zaufany plik binarny systemu Windows?

To jest kolejne pytanie dopytanie 1072540, „WinVerifyTrust, aby sprawdzić konkretny podpis?”.

Chcę napisać funkcję C ++ Nazwijmy toTrustedByUs w formie:

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

Chodzi o to, aby nadać tej funkcji ścieżkę do binarnego pliku .dll lub .exe podpisanego podpisem cyfrowym. ThepathToPublicKey ciąg jest ścieżką do klucza publicznego naszego konkretnego certyfikatu podpisującego.

Używanie kodu whttp://support.microsoft.com/kb/323809 to jest całkiem proste, aby sprawdzić, czypathToBinary plik jest w rzeczywistości zaufany przez system operacyjny.

Teraz jestem w tym samym miejscu co autor pytania 1072540, wiem, że system operacyjny ufa podpisującemu ten plik binarny, ale chcę wiedzieć, czy klucz RSA mojej organizacji jest tym, który podpisał plik binarny.

KB323809 pokazuje, jak wyodrębnić łańcuchy z certyfikatu osadzonego w naszym pliku binarnym. Ten przykład pokazuje, jak wyodrębnić ciągi znaków z certyfikatu podpisywania w jegoGetProgAndPublisherInfo funkcji, ale czuję się niekomfortowo, używając dopasowania sznurka, aby potwierdzić certyfikat.

Chciałbym wyodrębnić klucz publiczny z osadzonego podpisu i porównać go z kluczem publicznym, który odpowiada kluczowi prywatnemu, który podpisał mój plik binarny.

Dokumentacja dlaCryptMsgGetParam mówi, żeCMSG_SIGNER_CERT_ID_PARAM parametr 'Zwraca informacje na temat osoby podpisującej komunikat potrzebne do zidentyfikowania klucza publicznego osoby podpisującej'. Udało mi się uzyskać numer seryjny certyfikatu za pomocą tego klucza. Mój kod wygląda tak:

// 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");
}

Jest to zbliżone do tego, czego chcę, ale naprawdę chciałbym użyć klucza publicznego certyfikatu podpisującego do sprawdzenia, czy docelowy podpisany plik binarny został w rzeczywistości utworzony z moją konkretną parą kluczy publicznych / prywatnych.

UżywającCMSG_ENCRYPTED_DIGEST flag ten kod powiedzie się:

// 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);

Najważniejsze pytanie: Biorąc pod uwagę informacje o certyfikacie odkryte przezCryptQueryObject, jakiej techniki należy użyć, aby upewnić się, że plik docelowy został w rzeczywistości podpisany przy użyciu klucza prywatnego odpowiadającego kluczowi publicznemu, który jest dostępny dla mnie, gdy wykonywany jest powyższy kod?

questionAnswers(1)

yourAnswerToTheQuestion