怎样用代码签名数字证书对exe进行签名

对 EXE 文件进行代码签名是确保软件来源可信、防止被篡改以及消除 Windows “未知发布者”警告的关键步骤。自 2023 年 6 月起,行业标准要求代码签名证书的私钥必须存储在符合 FIPS 140-2 Level 2 或更高标准的硬件安全模块(HSM)或 USB 令牌中,因此签名过程通常涉及物理硬件或云 HSM 服务。

以下是使用代码签名证书对 EXE 文件进行签名的完整指南:

一、 准备工作

在开始签名之前,请确保具备以下条件和工具:

代码签名证书‌:

从受信任的证书颁发机构(CA)购买,如 GDCA等。
类型选择‌:
OV (组织验证)‌:价格较低,需积累微软 SmartScreen 信誉才能消除警告。
EV (扩展验证)‌:价格较高,审核严格,可立即获得微软 SmartScreen 信誉,消除“未知发布者”警告。
存储介质‌:证书私钥存储在 CA 提供的 USB 令牌(如 SafeNet Token)或云 HSM 中。

签名工具 (SignTool.exe)‌:

这是 Windows SDK 的一部分。如果未安装,请下载并安装最新版的 ‌Windows SDK‌。
通常路径为:C:\Program Files (x86)\Windows Kits\10\bin\<版本号>\x64\signtool.exe 或 x86\signtool.exe。

驱动程序与软件‌:

如果使用 USB 令牌,需安装对应的驱动程序和身份验证客户端(如 SafeNet Authentication Client)。
确保 USB 令牌已插入电脑并被系统识别。

管理员权限‌:

签名操作需要提升的权限,请以‌管理员身份‌运行命令提示符 (CMD) 或 PowerShell。

网络连接‌:

签名过程中需要连接时间戳服务器,请确保网络畅通。
二、 签名步骤
步骤 1:打开命令行工具

右键点击“开始”菜单,选择“Windows Terminal (Admin)”或“命令提示符 (管理员)”。

步骤 2:定位 SignTool

如果 signtool 未添加到系统环境变量 PATH 中,你需要进入其所在目录,或者在命令中使用完整路径。
例如:

cmd
cd “C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64”

(注意:请将版本号替换为你实际安装的 SDK 版本)

步骤 3:执行签名命令

根据你持有的证书类型(本地 USB 令牌或云 HSM),命令略有不同。

场景 A:使用本地 USB 令牌 (最常见)

当插入 USB 令牌后,SignTool 通常可以自动从证书存储中查找证书。

基本签名命令:‌

cmd
signtool sign /a /tr http://timestamp.digicert.com /td sha256 /fd sha256 “C:\Path\To\YourApp.exe”

参数详解:‌

/a:自动选择最佳的签名证书(从当前用户存储或 USB 令牌中)。如果自动选择失败,可能需要使用 /n “证书主题名称” 或 /sha1 <证书指纹> 来指定具体证书。
/tr <URL>:指定时间戳服务器的 URL。‌强烈建议添加此参数‌,以确保即使证书过期,签名依然有效。常用服务器包括:
DigiCert: http://timestamp.digicert.com
Sectigo: http://timestamp.sectigo.com
GlobalSign: http://timestamp.globalsign.com
/td sha256:指定时间戳使用的哈希算法(推荐 SHA256)。
/fd sha256:指定文件摘要算法(推荐 SHA256)。
“C:\Path\To\YourApp.exe”:你要签名的 EXE 文件的完整路径。

如果需要指定特定证书(当 /a 不起作用时):‌

cmd
signtool sign /n “Your Company Name” /tr http://timestamp.digicert.com /td sha256 /fd sha256 “C:\Path\To\YourApp.exe”

/n:指定证书的主题名称(Subject Name),即你在申请证书时填写的公司名。
场景 B:使用 PFX 文件 (仅限旧式标准证书或非强制硬件存储情况)

注意:自 2023 年 6 月起,新颁发的证书通常不支持导出私钥到 PFX 文件用于本地签名,必须使用硬件令牌。但如果你拥有旧的证书或特定允许导出的证书,可以使用以下命令:

cmd
signtool sign /f “C:\Path\To\Certificate.pfx” /p “YourPassword” /tr http://timestamp.digicert.com /td sha256 /fd sha256 “C:\Path\To\YourApp.exe”

/f:指定 PFX 证书文件路径。
/p:指定 PFX 文件的密码。
步骤 4:输入令牌密码 (仅 USB 令牌)

如果使用 USB 令牌,执行命令后,系统可能会弹出 SafeNet 或其他厂商的对话框,要求输入令牌的 PIN 码/密码。输入正确密码后,签名过程将自动完成。

三、 验证签名

签名完成后,务必验证签名是否成功应用。

方法 1:使用 SignTool 验证‌
在命令行中运行:

cmd
signtool verify /v /pa “C:\Path\To\YourApp.exe”

/v:详细模式,显示更多信息。
/pa:使用默认的 Windows 驱动程序签名验证策略(适用于大多数 EXE)。
如果成功,你将看到 “Successfully verified: …” 的消息。

方法 2:通过 Windows 资源管理器查看‌

右键点击已签名的 EXE 文件。
选择 ‌“属性” (Properties)‌。
点击 ‌“数字签名” (Digital Signatures)‌ 选项卡。
你应该能看到签名者列表。选中签名,点击 ‌“详细信息” (Details)‌。
在常规选项卡中,应显示 ‌“此数字签名正常” (This digital signature is OK)‌。
点击 ‌“查看证书” (View Certificate)‌ 可以检查证书的有效期和颁发者。
四、 常见问题与注意事项

为什么必须加时间戳 (/tr)?‌

代码签名证书有有效期(通常 1-3 年)。如果不加时间戳,证书过期后,Windows 会认为签名无效,用户会收到安全警告。
添加时间戳后,Windows 会检查签名时刻证书是否有效。只要签名时证书有效,即使现在证书已过期,签名依然被视为有效。

“未知发布者”警告仍未消除?‌

如果你使用的是 ‌OV 证书‌,微软 SmartScreen 需要时间积累信誉。随着你的软件被更多用户下载且无恶意报告,警告会逐渐消失。
如果你使用的是 ‌EV 证书‌,理论上应立即消除警告。如果仍出现,请检查:
是否正确添加了时间戳。
证书是否由受信任的根 CA 颁发。
系统时间是否正确。
尝试重新签名并确保使用了 /tr 参数。

USB 令牌找不到证书?‌

确保已安装最新的驱动程序和身份验证客户端。
尝试更换 USB 端口。
使用 certutil -store my 命令查看当前用户存储中是否可见证书。
确保以管理员身份运行命令提示符。

批量签名‌

如果有多个文件需要签名,可以编写一个简单的批处理脚本 (.bat) 或 PowerShell 脚本,循环调用 signtool sign 命令。

通过以上步骤,你可以成功地为 EXE 文件添加数字签名,提升软件的专业性和用户信任度。

上一篇:

:下一篇