c++ - 在非托管 C/C++ 中获取已签名 EXE 的 X509 代码签名证书序列号

标签 c++ c x509certificate unmanaged code-signing-certificate

我知道如何使用 C# DotNet 获取已签名 DLL 或 EXE 的代码签名证书详细信息,包括序列号。例如:

using System.Security.Cryptography.X509Certificates;
...
X509Certificate certinfo = X509Certificate.CreateFromSignedFile(filename);
byte[] serialno = certinfo.GetSerialNumber();

但是我如何使用非托管 C/C++ 来做到这一点?

我确实找到了 example如何遍历 C/++ 中的证书存储,但不是如何获取已签名 EXE 或 DLL 的证书详细信息。

最佳答案

这是一个如何解码可执行文件的 PKCS7 (CMS) 数据的示例。

DWORD dwEncoding, dwContentType, dwFormatType;
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;

// Get PKCS7 data

if(1)
{
    // Must be an absolute path.
    const wchar_t *filePath = L"C:\\Windows\\System32\\ntdll.dll";

    if(!CryptQueryObject(CERT_QUERY_OBJECT_FILE, filePath,
                         CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
                         CERT_QUERY_FORMAT_FLAG_BINARY, 0, &dwEncoding,
                         &dwContentType, &dwFormatType, &hStore,
                         &hMsg, NULL))
        return 1;
}
else
{
/*  Or do this if you want more control:

    - load exe into memory
    - find the certificate directory (WIN_CERTIFICATE)

    WIN_CERTIFICATE &winCert = ...

    CERT_BLOB certBlob = { winCert.dwLength, winCert.bCertificate };
    if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &certBlob, 
                         CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
                         CERT_QUERY_FORMAT_FLAG_BINARY, 0, &dwEncoding,
                         &dwContentType, &dwFormatType, &hStore,
                         &hMsg, NULL))
        return 1;
*/
}

// Get signers information

DWORD dwSignerCount = 0;
DWORD dwSignerCountSize = sizeof(dwSignerCount);
if(!CryptMsgGetParam(hMsg, CMSG_SIGNER_COUNT_PARAM, 0, &dwSignerCount, &dwSignerCountSize))
    return 1;

// The signer count seems to always be 1.
// Subsequent certificates can be retrieved like this:
// https://stackoverflow.com/q/36931928/2682312

for(DWORD i = 0; i < dwSignerCount; ++i)
{
    DWORD cbSignerInfo;
    if(!CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, i, NULL, &cbSignerInfo))
        return 1;

    PCMSG_SIGNER_INFO pSignerInfo = (PCMSG_SIGNER_INFO)malloc(cbSignerInfo);
    if(!CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, i, pSignerInfo, &cbSignerInfo))
        return 1;

    // Do something with pSignerInfo->SerialNumber

    // Enumerate nested certificates...

    free(pSignerInfo);
}

return 0;

关于c++ - 在非托管 C/C++ 中获取已签名 EXE 的 X509 代码签名证书序列号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54733752/

相关文章:

c++ - 为什么我们使用 char* 作为缓冲区,为什么不使用 boost::asio 中的字符串?

c - unsigned long long int 到 long double

java - 有人可以帮助我使用 BouncyCaSTLe 实现扩展主题备用名称吗?

java - 将 x509Certificate 转换为 byte[] 并反转

c++ - Node js 原生模块,从 Objective-C block 事件监听器触发回调不起作用

c++ - 为什么我的字符串长度打印为零?

c++ - 在 CreateProcess 之后调用 GetModuleFileNameEx 时出现 ERROR_INVALID_HANDLE

c - 二维莫顿解码功能 64bits

c - C 编程中的 sizeof() 行为

security - OpenSSL 和 GOST 引擎问题(静态链接)