Skip to content

命令行签名 ​

本教程使用 VSign KSP + Microsoft SignTool。先在同一 Windows 账户下完成 操作员安装 和 图形界面首签,再调用命令行。

准备环境 ​

  • 在 VSigntool 中开启 KSP 功能。
  • 安装 Windows SDK,找到 signtool.exe 的完整路径。
  • 在当前 Windows 用户的个人证书存储区中找到目标代码签名证书,记录其指纹。
  • 准备一个未签名的测试 EXE/DLL,以及可用的 RFC 3161 时间戳服务地址。

可以在 PowerShell 中列出当前用户的代码签名证书:

powershell
Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert |
    Select-Object Subject, Thumbprint, NotAfter

若目标证书不在列表中,先检查 KSP、操作员和 Windows 执行账户。不要改选操作员身份证书,也不要用自动选证书选项掩盖此问题。

执行签名 ​

设置以下三个环境变量,再运行命令:

变量内容
SIGNTOOL_PATH本机 signtool.exe 完整路径
SIGN_CERT_SHA1代码签名证书指纹,不是私钥或操作员安装 Token
TIMESTAMP_URL您的 RFC 3161 时间戳服务地址
powershell
$ErrorActionPreference = 'Stop'
foreach ($name in @('SIGNTOOL_PATH', 'SIGN_CERT_SHA1', 'TIMESTAMP_URL')) {
    if ([string]::IsNullOrWhiteSpace([Environment]::GetEnvironmentVariable($name))) {
        throw "请先设置环境变量 $name"
    }
}
& $env:SIGNTOOL_PATH sign /fd SHA256 /sha1 $env:SIGN_CERT_SHA1 /tr $env:TIMESTAMP_URL /td SHA256 "C:\release\your-app.exe"
if ($LASTEXITCODE -ne 0) { throw '签名失败或存在警告。' }
& $env:SIGNTOOL_PATH verify /pa /all /v /tw "C:\release\your-app.exe"
if ($LASTEXITCODE -ne 0) { throw '验签失败或缺少时间戳。' }

/sha1 用于按指纹选择证书,不是使用 SHA-1 签名;文件摘要由 /fd SHA256 指定。/tr 后的 /td SHA256 设置时间戳摘要。示例读取当前用户证书存储区,不使用 /sm 切换到计算机存储区。

用统一脚本接入流水线 ​

下载 签名与验签脚本,保存为项目内的 ci/sign-and-verify.ps1。脚本使用上述变量,并检查文件类型、目标证书、签名状态和时间戳。它仅接受未签名的 EXE/DLL;验证失败会返回非零状态,不应发布该文件。

powershell
& .\ci\sign-and-verify.ps1 -FilePath ".\release\your-app.exe"
if ($LASTEXITCODE -ne 0) { throw '签名任务未通过。' }

此脚本会修改输入文件。请使用构建产物副本,或由流水线保存独立的已签名产物。具体调用方式见 GitLab CI 集成。

排查命令行失败 ​

先运行 whoami,确认当前账户与安装操作员的账户一致。若桌面签名正常而命令行失败,继续检查 KSP 是否启用、证书是否在当前用户存储区、SignTool 是否匹配运行环境,以及时间戳服务是否可访问。

依据:VSign KSP 与 SignTool 集成、Microsoft SignTool 参数说明。