代码签名不只用于 .exe。企业发布工具时,经常需要处理 PowerShell 脚本、批处理文件、MSI 安装包和 ClickOnce 应用。不同对象的签名方式、验证入口和失败表现并不一样。把签名步骤写进发布脚本,能减少“开发环境正常、用户环境被拦截”的情况。
本文讨论常见 Windows 发布对象的签名实践,不涉及绕过系统安全策略。证书类型和申请流程可参考本站代码签名证书栏目,具体命令和平台策略以当期文档为准。
一、PowerShell 脚本签名
PowerShell 的执行策略会检查脚本来源。对需要分发的 .ps1 文件,可以使用代码签名证书签名,并在签名后通过 Get-AuthenticodeSignature 查看状态。执行策略不是权限边界,不能把它当成安全防护;签名的作用是让管理员确认脚本发布者,并在策略允许时正常加载。
签名前确认脚本使用 UTF-8 编码并保存为无 BOM 或符合团队规范,避免签名后因编辑器自动转换编码导致哈希变化。脚本中若包含下载、解压、注册服务等动作,应在发布说明中写清用途,减少终端安全软件的误报。
二、MSI 安装包签名
MSI 的签名对象是安装包文件本身。若 MSI 内嵌了 EXE、DLL 或脚本,建议先签内部文件,再签 MSI 外层。签名工具会写入 Authenticode 签名,修改 MSI 内容后签名失效。构建流程应将签名安排在打包完成后,后续步骤只做复制和校验,不再改写文件。
签名时统一添加时间戳,避免证书到期后历史安装包无法验证。发布前在干净系统执行安装、修复、升级和卸载,查看 Windows 是否显示预期发布者。若企业使用软件分发平台,确认平台是否校验签名链和时间戳。
三、ClickOnce 清单签名
ClickOnce 应用涉及应用清单和部署清单。签名对象不仅是可执行文件,还包括清单文件。清单中记录了文件哈希、版本和发布者信息,任何文件变更都可能导致清单与产物不匹配。建议在发布目录生成后,按“程序文件、应用清单、部署清单”的顺序处理,并在签名后执行清单校验。
ClickOnce 的更新机制会对比版本和清单。证书更换后,旧版本升级到新版本时可能出现发布者变化提示。提前规划证书续期,保持主体名称稳定,可以减少用户困惑。若必须变更主体,准备升级说明和技术支持方案。
四、批处理与驱动安装脚本
批处理文件本身对 Authenticode 签名的支持有限,很多场景是通过打包成 EXE、MSI 或 PowerShell 脚本后再签名。对驱动安装包,除了安装程序,还要关注 .cat 目录文件和驱动文件的签名状态。不要只签安装壳而忽略内部驱动,否则安装后仍可能加载失败。
签名后的文件应存放在只读发布目录,避免构建脚本后续写入版本资源。对外发布的压缩包应记录哈希,用户解压后可以核对文件是否与签名版本一致。
五、验签与故障排查
- 使用系统工具查看签名状态、签名者和时间戳,不要只看文件属性中的“数字签名”标签。
- 确认证书链完整,中间证书已正确安装或随包提供。
- 检查签名后是否还有构建步骤修改文件,尤其是版本信息和资源写入。
- 确认时间戳服务可访问,签名日志中没有超时或失败记录。
- 在无开发环境的干净虚拟机中测试,排除本机证书缓存影响。
如果验签显示“哈希不匹配”,通常说明签名后文件被改动;显示“证书链不可信”,检查根证书和中间证书;显示“无时间戳”,检查签名命令参数。不要把失败产物直接发布后再排查,用户侧的提示会放大问题。
六、发布流程建议
- 列出所有需要签名的对象:脚本、程序、库、安装包、清单。
- 确定签名顺序,内部文件先签,外层容器后签。
- 统一添加时间戳,保存签名日志和证书序列号。
- 签名后执行自动验签,失败即阻断发布。
- 在干净环境安装和升级,记录系统提示。
- 归档未签名产物、签名产物和哈希清单。
SSLDUN 自 2017 年起通过合同方式获得 Certum 相关产品授权,可协助企业准备代码签名证书材料并沟通审核问题。证书能否签发、签名是否被平台接受,仍取决于 CA 审核和平台规则。把发布流程做成可重复的步骤,比每次临时处理更稳妥。
七、CI 环境中的签名密钥管理
把签名接入持续集成后,密钥介质的管理比命令本身更重要。硬件令牌需要插在固定构建机上,构建任务只能通过受控服务调用签名接口,不能把私钥导出到普通构建节点。每个签名请求应记录发起人、版本号、产物哈希和签名时间,异常请求可以追溯。
对多产品线团队,建议按产品分配签名权限,避免一个账号可以签署所有产物。签名服务与构建日志分开保存,发布人员只能拿到签名后的只读产物。证书续期时先在测试流水线验证,再切换生产,防止新证书链或时间戳配置导致全量构建失败。
八、常见问题
问:脚本签名后,编辑器提示保存会怎样?
答:保存可能改变文件字节,导致签名失效。签名后的脚本应设为只读,修改后重新签名。
问:MSI 内文件未签名,只签外层可以吗?
答:外层签名有效,但内部文件解包后可能显示未知发布者。建议按发布要求分别签名。
问:ClickOnce 更换证书后能否继续升级?
答:可以升级,但用户可能看到发布者变化提示。提前测试并准备说明,避免升级中断。