You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Windows API检查驱动是否使用吊销证书签名?

检测驱动签名证书吊销状态的正确方法

问题根源

你当前的WinVerifyTrust调用存在两个关键问题:

  • 错误地通过GetLastError()获取失败原因,WinVerifyTrust的失败信息直接通过返回的HRESULT传递,而非GetLastError。
  • 未针对内核模式驱动的签名验证策略做适配,普通Authenticode验证逻辑和内核驱动的签名检查规则存在差异。

修正后的WinVerifyTrust调用

以下是调整后的代码,能正确匹配内核驱动加载时的证书吊销检查逻辑:

#include <wintrust.h>
#include <softpub.h>
#include <mscat.h>

#pragma comment(lib, "wintrust.lib")

BOOL IsDriverCertRevoked(LPCWSTR pwszFileName) {
    BOOL bRevoked = FALSE;
    HRESULT hr;

    WINTRUST_FILE_INFO wtfi = { 0 };
    wtfi.cbStruct = sizeof(WINTRUST_FILE_INFO);
    wtfi.pcwszFilePath = pwszFileName;
    wtfi.hFile = NULL;

    WINTRUST_DATA wtd = { 0 };
    wtd.cbStruct = sizeof(WINTRUST_DATA);
    wtd.dwUIChoice = WTD_UI_NONE; // 禁用UI弹窗
    wtd.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; // 检查整个证书链的吊销状态
    wtd.dwUnionChoice = WTD_CHOICE_FILE;
    wtd.pFile = &wtfi;
    wtd.dwStateAction = WTD_STATEACTION_VERIFY;
    wtd.dwProvFlags = WTD_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT | WTD_USE_DEFAULT_OSVER_CHECK; // 适配驱动OS版本验证规则

    // 使用适配内核驱动的通用验证策略GUID
    GUID wvtProvGuid = WINTRUST_ACTION_GENERIC_VERIFY_V2;

    hr = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &wvtProvGuid, &wtd);

    if (hr == CERT_E_REVOKED) {
        // 明确检测到证书已吊销
        bRevoked = TRUE;
    } else if (FAILED(hr)) {
        // 其他验证错误(如无签名、证书过期等),可按需处理
    }

    // 清理验证状态数据
    wtd.dwStateAction = WTD_STATEACTION_CLOSE;
    WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &wvtProvGuid, &wtd);

    return bRevoked;
}

关键调整说明

  • 错误处理逻辑:直接判断返回的HRESULT值,CERT_E_REVOKED(0x800B010C)是证书吊销的明确标识。
  • 验证策略匹配:使用WINTRUST_ACTION_GENERIC_VERIFY_V2 GUID,该策略覆盖了内核模式驱动的签名验证规则。
  • 参数优化:添加WTD_USE_DEFAULT_OSVER_CHECK确保驱动的OS版本兼容性检查和内核加载时的逻辑一致,避免误判。

更灵活的手动证书链检查

如果需要自定义吊销检查规则(如离线检查、指定吊销服务器),可以使用CertGetCertificateChain和CertVerifyCertificateChainPolicy手动构建并验证证书链:

BOOL CheckDriverCertRevocationManual(LPCWSTR pwszFileName) {
    BOOL bRevoked = FALSE;
    HCERTSTORE hStore = NULL;
    PCCERT_CONTEXT pCertContext = NULL;
    PCCERT_CHAIN_CONTEXT pChainContext = NULL;
    CERT_CHAIN_POLICY_PARA policyPara = { 0 };
    CERT_CHAIN_POLICY_STATUS policyStatus = { 0 };

    // 提取驱动文件的签名证书
    if (!CryptQueryObject(CERT_QUERY_OBJECT_FILE,
                          pwszFileName,
                          CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
                          CERT_QUERY_FORMAT_FLAG_BINARY,
                          0,
                          NULL,
                          NULL,
                          NULL,
                          &hStore,
                          NULL,
                          (const void**)&pCertContext)) {
        goto Cleanup;
    }

    // 构建完整证书链
    CERT_CHAIN_PARA chainPara = { 0 };
    chainPara.cbSize = sizeof(CERT_CHAIN_PARA);
    if (!CertGetCertificateChain(NULL,
                                 pCertContext,
                                 NULL,
                                 hStore,
                                 &chainPara,
                                 CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
                                 NULL,
                                 &pChainContext)) {
        goto Cleanup;
    }

    // 验证证书链的吊销状态
    policyPara.cbSize = sizeof(CERT_CHAIN_POLICY_PARA);
    policyStatus.cbSize = sizeof(CERT_CHAIN_POLICY_STATUS);
    if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_BASE,
                                          pChainContext,
                                          &policyPara,
                                          &policyStatus)) {
        goto Cleanup;
    }

    // 检查是否因吊销导致验证失败
    if (policyStatus.dwError == CERT_E_REVOKED || 
        policyStatus.dwError == CRYPT_E_REVOCATION_OFFLINE) {
        bRevoked = TRUE;
    }

Cleanup:
    if (pChainContext) CertFreeCertificateChain(pChainContext);
    if (pCertContext) CertFreeCertificateContext(pCertContext);
    if (hStore) CertCloseStore(hStore, 0);
    return bRevoked;
}

补充说明

  • Sysinternals的SigCheck默认不启用吊销检查,需添加-r参数触发:sigcheck.exe -r <驱动文件路径>。
  • 内核驱动的吊销检查会严格遵循微软代码签名的官方规则,上述API调用完全匹配内核加载时的验证逻辑。

内容的提问来源于stack exchange,提问作者user5716274

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:40:42