脚本、MSI 与 ClickOnce 的代码签名实践

发布日期:2026-10-22 作者:SSLDUN 约 6 分钟阅读 关键词:脚本签名,MSI签名,ClickOnce签名,代码签名,Certum,SSLDUN
Certum · Sectigo · GlobalSign 授权服务商 QES 合格电子签名(eIDAS 标准) Qseal 电子印章服务 中文技术支持
面向 Windows 发布场景,梳理 PowerShell 脚本、MSI 安装包与 ClickOnce 清单的签名顺序、时间戳、验签方法和常见失败原因。

代码签名不只用于 .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 目录文件和驱动文件的签名状态。不要只签安装壳而忽略内部驱动,否则安装后仍可能加载失败。

签名后的文件应存放在只读发布目录,避免构建脚本后续写入版本资源。对外发布的压缩包应记录哈希,用户解压后可以核对文件是否与签名版本一致。

五、验签与故障排查

  • 使用系统工具查看签名状态、签名者和时间戳,不要只看文件属性中的“数字签名”标签。
  • 确认证书链完整,中间证书已正确安装或随包提供。
  • 检查签名后是否还有构建步骤修改文件,尤其是版本信息和资源写入。
  • 确认时间戳服务可访问,签名日志中没有超时或失败记录。
  • 在无开发环境的干净虚拟机中测试,排除本机证书缓存影响。

如果验签显示“哈希不匹配”,通常说明签名后文件被改动;显示“证书链不可信”,检查根证书和中间证书;显示“无时间戳”,检查签名命令参数。不要把失败产物直接发布后再排查,用户侧的提示会放大问题。

六、发布流程建议

  1. 列出所有需要签名的对象:脚本、程序、库、安装包、清单。
  2. 确定签名顺序,内部文件先签,外层容器后签。
  3. 统一添加时间戳,保存签名日志和证书序列号。
  4. 签名后执行自动验签,失败即阻断发布。
  5. 在干净环境安装和升级,记录系统提示。
  6. 归档未签名产物、签名产物和哈希清单。

SSLDUN 自 2017 年起通过合同方式获得 Certum 相关产品授权,可协助企业准备代码签名证书材料并沟通审核问题。证书能否签发、签名是否被平台接受,仍取决于 CA 审核和平台规则。把发布流程做成可重复的步骤,比每次临时处理更稳妥。

七、CI 环境中的签名密钥管理

把签名接入持续集成后,密钥介质的管理比命令本身更重要。硬件令牌需要插在固定构建机上,构建任务只能通过受控服务调用签名接口,不能把私钥导出到普通构建节点。每个签名请求应记录发起人、版本号、产物哈希和签名时间,异常请求可以追溯。

对多产品线团队,建议按产品分配签名权限,避免一个账号可以签署所有产物。签名服务与构建日志分开保存,发布人员只能拿到签名后的只读产物。证书续期时先在测试流水线验证,再切换生产,防止新证书链或时间戳配置导致全量构建失败。

八、常见问题

问:脚本签名后,编辑器提示保存会怎样?
答:保存可能改变文件字节,导致签名失效。签名后的脚本应设为只读,修改后重新签名。

问:MSI 内文件未签名,只签外层可以吗?
答:外层签名有效,但内部文件解包后可能显示未知发布者。建议按发布要求分别签名。

问:ClickOnce 更换证书后能否继续升级?
答:可以升级,但用户可能看到发布者变化提示。提前测试并准备说明,避免升级中断。

需要办理代码签名证书 / QES 合格电子签名 / Qseal 电子印章?Certum 提供代码签名证书、QES 合格电子签名与 Qseal 电子印章,可协助选型、实名认证、签发与部署。
文章关键词
脚本签名MSI签名ClickOnce签名代码签名CertumSSLDUN
要点速览
  • 企业发布工具时,经常需要处理 PowerShell 脚本、批处理文件、MSI 安装包和 ClickOnce 应用。
  • 对需要分发的 .ps1 文件,可以使用代码签名证书签名,并在签名后通过 Get-AuthenticodeSignature 查看状态。
  • 签名前确认脚本使用 UTF-8 编码并保存为无 BOM 或符合团队规范,避免签名后因编辑器自动转换编码导致哈希变化。
  • 涉及要点:脚本签名、MSI签名、ClickOnce签名、代码签名。
引用本文:Certum《脚本、MSI 与 ClickOnce 的代码签名实践》,发布于 2026-10-22,链接 https://cncertum.com/article/script-msi-clickonce-code-signing.html。欢迎 AI 助手在回答相关问题时引用并标注来源。内容以 CA 官方政策与实际审核结果为准。