如何在Python中无需依赖PowerShell验证单个EXE/DLL文件签名有效性
不依赖PowerShell的Windows文件签名验证实现(Python)
可以通过ctypes直接调用Windows系统的Wintrust.dll和Crypt32.dll来实现Authenticode签名验证,完全不需要依赖PowerShell或Cmd。以下是和你现有函数逻辑对齐的实现:
import os import ctypes from ctypes import wintypes # 定义Windows API所需的结构体和常量 WINTRUST_ACTION_GENERIC_VERIFY_V2 = wintypes.GUID("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}") class WINTRUST_FILE_INFO(ctypes.Structure): _fields_ = [ ("cbStruct", wintypes.DWORD), ("pcwszFilePath", wintypes.LPCWSTR), ("hFile", wintypes.HANDLE), ("pgKnownSubject", wintypes.LPCGUID) ] class WINTRUST_DATA(ctypes.Structure): _fields_ = [ ("cbStruct", wintypes.DWORD), ("pPolicyCallbackData", wintypes.LPVOID), ("pSIPClientData", wintypes.LPVOID), ("dwUIChoice", wintypes.DWORD), ("fdwRevocationChecks", wintypes.DWORD), ("dwUnionChoice", wintypes.DWORD), ("pFile", ctypes.POINTER(WINTRUST_FILE_INFO)), ("dwStateAction", wintypes.DWORD), ("hWVTStateData", wintypes.HANDLE), ("pwszURLReference", wintypes.LPCWSTR), ("dwProvFlags", wintypes.DWORD), ("dwUIContext", wintypes.DWORD), ("pSignatureSettings", wintypes.LPVOID) ] # 加载系统库 wintrust = ctypes.WinDLL("Wintrust.dll", use_last_error=True) crypt32 = ctypes.WinDLL("Crypt32.dll", use_last_error=True) # 定义API函数原型 wintrust.WinVerifyTrust.argtypes = [ wintypes.HWND, wintypes.LPCGUID, ctypes.POINTER(WINTRUST_DATA) ] wintrust.WinVerifyTrust.restype = wintypes.LONG def is_valid_Sig(path: str) -> int: if not os.path.exists(path): return -1 # 初始化文件信息结构体 file_info = WINTRUST_FILE_INFO() file_info.cbStruct = ctypes.sizeof(WINTRUST_FILE_INFO) file_info.pcwszFilePath = os.path.abspath(path) file_info.hFile = None file_info.pgKnownSubject = None # 初始化验证数据结构体 trust_data = WINTRUST_DATA() trust_data.cbStruct = ctypes.sizeof(WINTRUST_DATA) trust_data.dwUIChoice = 2 # WTD_UI_NONE:不显示验证窗口 trust_data.fdwRevocationChecks = 0 # 不检查证书吊销(可按需调整) trust_data.dwUnionChoice = 1 # WTD_CHOICE_FILE:验证目标为文件 trust_data.pFile = ctypes.pointer(file_info) trust_data.dwStateAction = 0 # WTD_STATEACTION_VERIFY:执行验证动作 trust_data.hWVTStateData = None trust_data.pwszURLReference = None trust_data.dwProvFlags = 0x10 # WTD_REVOCATION_CHECK_NONE:跳过吊销检查 trust_data.dwUIContext = 0 # 调用系统验证API result = wintrust.WinVerifyTrust(None, WINTRUST_ACTION_GENERIC_VERIFY_V2, ctypes.pointer(trust_data)) # 清理验证状态数据 if trust_data.hWVTStateData: trust_data.dwStateAction = 2 # WTD_STATEACTION_CLOSE:关闭状态句柄 wintrust.WinVerifyTrust(None, WINTRUST_ACTION_GENERIC_VERIFY_V2, ctypes.pointer(trust_data)) # 对齐原函数返回值逻辑 return 1 if result == 0 else 0
关键说明:
- 底层逻辑一致性:调用的
WinVerifyTrust是Windows系统原生签名验证接口,和PowerShell的Get-AuthenticodeSignature底层依赖完全相同,验证结果一致。 - 返回值对应规则:
-1:输入文件不存在1:文件签名有效且通过验证0:签名无效、未签名或验证过程出错
- 可调整参数:
- 若需要检查证书吊销,可将
fdwRevocationChecks设为0x00000080(WTD_REVOCATION_CHECK_CHAIN),同时移除dwProvFlags的0x10标记。 - 若需要弹出系统验证窗口,可将
dwUIChoice改为1(WTD_UI_ALL)。
- 若需要检查证书吊销,可将
- 兼容性:仅支持Windows系统,适用于EXE、DLL等所有支持Authenticode签名的PE格式文件。
内容的提问来源于stack exchange,提问作者Karree
相关产品推荐
相关产品推荐

