signtool.exe 为 .net 程序集签名需使用有效可导出私钥的代码签名证书,添加 authenticode 签名节而不修改 il;签名后须验证有效性并确保时间戳、证书链及依赖项均合规。

如何用 signtool.exe 为 .exe/.dll 签名
签名程序集本身不改变 IL,而是向 PE 文件添加 Authenticode 签名节。.NET 程序集(.exe/.dll)必须是已编译的托管二进制(非源码),且不能是仅含 PDB 的文件。
- 确保已安装 Windows SDK 或 Visual Studio(含
signtool.exe,通常位于"C:\Program Files (x86)\Windows Kits\10\bin\<version>\x64\signtool.exe"</version>) - 使用有效代码签名证书(.pfx 文件),私钥需可导出且未被标记为“不可导出”
- 签名命令示例:
signtool sign /f "mycert.pfx" /p "password" /t "http://timestamp.digicert.com" MyApp.exe
- 若提示
SignTool Error: No certificates were found that met all the given criteria.,检查证书是否导入到当前用户或本地计算机的Personal存储,并确认其增强型密钥用法(EKU)包含Code Signing - /tr 和 /td 参数用于 SHA-2 时间戳(推荐),避免旧版 /t 在 2025 年后失效
为什么给 .NET 程序集签名后仍被杀毒软件拦截
Authenticode 签名不等于“免检”,尤其对新证书、低信誉发布者或无时间戳的签名,Windows SmartScreen 和部分 AV 仍会警告。
- 签名只是证明“此文件来自某实体”,不提供安全担保;首次分发时仍需积累信誉(如通过 Microsoft SmartScreen Reputation Service)
- 若程序集依赖未签名的 native DLL(如 C++ 运行时或驱动),整个信任链断裂,系统可能忽略 .NET 部分签名
- 调试版程序集(含
DebuggableAttribute或 PDB 路径残留)易被误判为开发中软件,建议发布前用ilasm+ildasm清除调试元数据,或用dotnet publish -c Release --self-contained true构建干净输出 - 签名后务必用
signtool verify /pa MyApp.exe验证签名有效性,再用certutil -verifystore my检查证书链完整性
为 MSI 安装包签名的特殊注意事项
MSI 是数据库文件,不是 PE 格式,不能直接用 signtool sign —— 必须用 signtool sign /fd SHA256 /a 并指定 /d(描述)和 /du(URL),否则 Windows Installer 可能拒绝执行。
- MSI 签名必须使用 /a(自动选择证书)或显式指定 /f,且证书必须支持
Code SigningEKU 和Document Signing(某些 CA 要求两者兼备) - 签名前确保 MSI 已关闭所有打开句柄(例如未在 Orca 中打开、未被 msiexec 占用),否则报错
SignTool Error: The specified file could not be opened - 若用 WiX Toolset 构建 MSI,可在
WixProj中配置<signoutput>true</signoutput>,并设置<signertoolpath></signertoolpath>指向signtool.exe,但需注意:WiX v3 默认调用旧版 signtool,v4+ 推荐手动 post-build 签名更可控 - 签名后用
msiexec /a package.msi /qn测试静默安装是否仍触发 UAC 提示;若提示“无法验证发布者”,说明签名未被系统信任或时间戳服务不可达
PowerShell 脚本或 ClickOnce 应用怎么签
PowerShell 脚本(.ps1)和 ClickOnce 发布物(.application + .manifest)签名机制完全不同,不能混用 PE 签名流程。
- .ps1 文件必须用
Set-AuthenticodeSignaturecmdlet,且证书需导入到CurrentUser\Trusted Publishers或LocalMachine\Trusted Publishers才能绕过ExecutionPolicy限制 - ClickOnce 应用需先用
mage.exe -sign签署部署清单(.application)和应用程序清单(.manifest),且两个文件必须用同一证书;mage.exe路径通常在"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\mage.exe" - 若 ClickOnce 安装后提示“部署清单签名无效”,常见原因是:部署清单时间戳与应用程序清单不一致、证书私钥权限不足(运行
mage -cc清缓存后再重签)、或 IIS 未正确设置 .manifest MIME 类型(应为application/x-ms-manifest) - PowerShell 签名后仍被阻止?检查
Get-ExecutionPolicy -Scope CurrentUser是否为RemoteSigned或更低;仅AllSigned会强制校验本地脚本签名
/tr https://rfc3161timestamp.globalsign.com/advanced 这类 HTTPS 地址。








