本文面向开发、运维、打包负责人,兼顾原理、差异、选型、落地脚本、坑点,适合放在知识库、内部文档,也可用于对外科普。 核心前提:Certum SimplySign 是 Certum 官方的云端 HSM 代码签名方案,无实体 U 盾,私钥全程托管在符合 FIPS 140-2 Level 3 的云端密码机,私钥无法导出,满足当前 CA/B 论坛对代码签名密钥硬件保护的强制要求。 时间戳统一地址:
http://time.certum.pl,固定 SHA256。
很多人以为只是价格差别,实际是验证等级、证书能力、使用边界完全不同。
✅ 定位:企业商用普通代码签名,性价比款
✅ 验证方式:组织信息核验(营业执照、工商公示信息、电话回拨核验企业)
✅ 签名对象:.exe .dll .msi .cab .ocx .jar .ps1 VBA宏 等普通应用、插件、工具
✅ 优势
价格更低,适合长期批量发布桌面软件、内部工具
支持 SimplySign 云,免 U 盾,支持 Windows CI/CD 集成
自带时间戳,签名文件到期后,签名依旧有效(时间戳作用) 硬性限制(非常关键)
不支持 Windows 内核驱动 .sys 签名,不能用于 WHQL 认证
SmartScreen 没有初始高信誉,软件分发量上去之后,信誉会慢慢积累,新包容易报 “未知发布者” 警告
每月签名额度上限:5000 次(OV、EV 云签共用这个限额)
证书最长有效期 459 天;多年套餐是服务周期,到期前代理商协助免费重签,材料不用重复提交
开源版 OV 云签补充:单独产品线,价格更低,证书展示
Open Source Developer,禁止商用闭源软件,只适合开源项目发布。
✅ 定位:高信任等级代码签名,驱动、WHQL、高安全分发首选 ✅ 验证方式:EV 增强深度核验,除企业资质,额外核验企业实际经营地址、负责人、控制权,审核更严格、周期略长 ✅ 签名对象:普通程序 + Windows 内核驱动.sys,支持 WHQL 提交、Office 宏大规模分发 ✅ 优势
微软信任等级更高,自带初始信誉,SmartScreen 警告更少,用户侧体验更好
可以直接用于驱动签名、WHQL 流程,这是 OV 云签做不到的核心差异
和 OV 云签共用一套 SimplySign 客户端、一套签名命令、一套 CI 脚本,集成方式完全一致,只是证书权限不同 ⚠️ 同样限制:每月 5000 签名上限、必须联网签名、私钥不可导出
表格
| 项目 | OV SimplySign 云签 | EV SimplySign 云签 |
|---|---|---|
| 适用场景 | 普通桌面 exe、dll、msi、宏、内部工具 | 驱动 sys、WHQL、高信誉商用软件、宏分发 |
| 能否做 WHQL / 内核驱动 | ❌ 不支持 | ✅ 支持 |
| SmartScreen 信誉 | 从零慢慢积累 | 初始高信誉,弹窗更少 |
| 验证强度 | 标准组织核验 | 深度增强 EV 核验 |
| 硬件形态 | 云端 HSM、无 U 盾 | 云端 HSM、无 U 盾 |
| CI 集成脚本 | 通用一套 signtool 脚本 | 脚本命令和 OV 完全一样 |
| 签名上限 | 每月 5000 次 | 每月 5000 次 |
| 离线签名 | ❌ 需要联网 | ❌ 需要联网 |
补充硬件版:Certum 也有 OV/EV 硬件 Token 版本,带实体 U 盾,可以离线签名;缺点是 CI 服务器需要插 USB,流水线自动化非常麻烦,现在自动化场景优先云签。
证书申请通过后,在 SimplySign 平台创建账号,绑定证书;密钥在云端 HSM 内部生成,永远不会下载到本地
Windows 机器安装 SimplySign Desktop 客户端,保持后台托盘运行、账号登录状态
你调用微软原生 signtool.exe(Windows SDK 自带工具,不是 Certum 自研工具)发起签名
SimplySign 客户端拦截 signtool 的签名请求,把签名请求转发到云端 HSM
触发二次身份校验:手机 SimplySign App 收到推送,人工确认授权签名
HSM 完成签名运算,返回签名数据,signtool 写入文件,同时附加 Certum 时间戳
同一个 PowerShell/Bat 脚本里批量签一批文件,属于同一个签名会话,只需要手机确认一次;多次独立调用 signtool 命令,会多次推送确认。
这也是 CI 自动化最大的特点:默认需要人工手机确认,不是无人值守自动签;SimplySign 有企业预授权模式,可配置免 App 确认(适合严格内部可信流水线,需要单独申请开通)。
重要:Linux Runner 没有官方 SimplySign Desktop 客户端。Linux 构建机不能直接跑这套方案,只能用第三方 pkcs11 桥接方案(ssign-pkcs11 + osslsigncode),属于社区方案,稳定性弱于 Windows 客户端,生产环境优先 Windows Agent。
无论 Jenkins / Azure DevOps / GitHub Actions(自托管 Windows),都必须先做好这几步
Windows 构建机 / Agent 安装 SimplySign Desktop,登录你的 SimplySign 账号,证书状态正常
安装 Windows SDK,拿到 signtool.exe(推荐 10/11 SDK,优先 x64 版本)
服务器网络放行,可以访问外网,能连通 time.certum.pl(时间戳)、Certum SimplySign 服务
提前确认证书标识:
方式 A(简单):证书主题名称 /n "你的公司全称"
方式 B(推荐 CI 防冲突):证书 SHA1 指纹 /sha1 XXXXX,不会因为重签、同名证书选错
Agent 不要锁屏、不要自动退出 SimplySign 托盘进程,锁屏会导致客户端断开,签名卡住
重点:OV 和 EV 脚本命令完全一模一样,只需要替换证书名称或者指纹,不需要改签名逻辑
sign.bat@echo off setlocal enabledelayedexpansion :: ========== 配置区,OV/EV切换只改这里 ========== set "SIGNTOOL=C:Program Files (x86)Windows Kits10in10.0.22621.0x64signtool.exe" set "CERT_ID=你的公司全称" :: 如果用指纹模式替换上行:set "CERT_ID=abcdef0123456789abcdef0123456789abcdef01" set "USE_SHA1=0" :: 0=用名称/n,1=用指纹/sha1 set "TS_URL=http://time.certum.pl" set "HASH=SHA256" set "SCAN_DIR=.dist" set "FILE_FILTER=*.exe *.dll *.msi *.cab *.ocx" :: ============================================== if not exist "%SIGNTOOL%" ( echo [ERROR] signtool 不存在,请检查SDK路径 exit /b 1 ) echo ========================================= echo Certum SimplySign Cloud Sign Script echo CERT: %CERT_ID% echo Timestamp: %TS_URL% echo ========================================= for %%f in (%SCAN_DIR%\%FILE_FILTER%) do ( echo Signing: %%f if %USE_SHA1% equ 1 ( "%SIGNTOOL%" sign /sha1 %CERT_ID% /fd %HASH% /tr %TS_URL% /td %HASH% /v "%%f" ) else ( "%SIGNTOOL%" sign /n "%CERT_ID%" /fd %HASH% /tr %TS_URL% /td %HASH% /v "%%f" ) if !errorlevel! neq 0 ( echo [ERROR] 签名失败 %%f exit /b !errorlevel! ) ) echo. echo 开始校验所有签名 for %%f in (%SCAN_DIR%\%FILE_FILTER%) do ( "%SIGNTOOL%" verify /pa /all "%%f" if !errorlevel! neq 0 ( echo [ERROR] 校验失败 %%f exit /b !errorlevel! ) ) echo ✅ 全部签名+校验完成 endlocal exit /b 0
Sign-CertumCloud.ps1<#
.DESCRIPTION
Certum SimplySign OV / EV 云签脚本,通用,切换证书只修改配置
#>
# 配置区
$signtool = "C:Program Files (x86)Windows Kits10in10.0.22621.0x64signtool.exe"
$certName = "你的公司全称"
$certThumbprint = "" # 填写指纹就优先指纹模式
$timestamp = "http://time.certum.pl"
$hashAlg = "SHA256"
$targetPath = "./dist"
$patterns = @("*.exe","*.dll","*.msi","*.cab","*.ocx")
# 检查signtool
if(-not (Test-Path $signtool)){
Write-Error "signtool 未找到,请检查Windows SDK"
exit 1
}
# 收集文件
$files = @()
foreach($p in $patterns){
$files += Get-ChildItem -Path $targetPath -Filter $p -Recurse
}
if($files.Count -eq 0){
Write-Warning "未找到待签名文件"
exit 0
}
Write-Host "一共找到 $($files.Count) 个待签名文件" -ForegroundColor Cyan
# 批量签名(同会话一次App确认)
foreach($f in $files){
Write-Host "签名 $($f.FullName)"
$args = @("sign","/fd",$hashAlg,"/tr",$timestamp,"/td",$hashAlg,"/v")
if(-not [string]::IsNullOrWhiteSpace($certThumbprint)){
$args += "/sha1"
$args += $certThumbprint
}else{
$args += "/n"
$args += "`"$certName`""
}
$args += $f.FullName
& $signtool @args
if($LASTEXITCODE -ne 0){
Write-Error "签名失败:$($f.FullName)"
exit $LASTEXITCODE
}
}
# 签名校验
Write-Host "`n校验签名..." -ForegroundColor Cyan
foreach($f in $files){
& $signtool verify /pa /all $f.FullName
if($LASTEXITCODE -ne 0){
Write-Error "校验失败:$($f.FullName)"
exit $LASTEXITCODE
}
}
Write-Host "`n✅ 签名全部成功" -ForegroundColor Greenpipeline {
agent { label 'windows-build-agent' }
environment {
TS_URL = 'http://time.certum.pl'
}
stages {
stage('Build Package') {
steps {
echo "编译打包逻辑"
}
}
stage('Certum Cloud Sign (OV/EV通用)') {
steps {
powershell """
.\Sign-CertumCloud.ps1
"""
}
}
stage('归档产物') {
steps {
archiveArtifacts artifacts: 'dist/**', fingerprint: true
}
}
}
post {
failure {
echo "签名流水线失败:检查SimplySign客户端是否在线、手机App是否确认、网络连通性"
}
}
}name: Build And Certum Sign on: workflow_dispatch jobs: buildsign: runs-on: windows-self-hosted steps: - name: 拉取代码 uses: actions/checkout@v4 - name: 执行签名脚本 shell: pwsh run: .Sign-CertumCloud.ps1 - name: 上传签名后文件 uses: actions/upload-artifact@v4 with: name: signed-output path: dist/
$cert = Get-ChildItem Cert:CurrentUserMy -CodeSigningCert | Where-Object {$_.Subject -match "你的公司全称"}
Set-AuthenticodeSignature -FilePath ".deploy.ps1" -Certificate $cert -TimestampServer "http://time.certum.pl" -HashAlgorithm SHA256osslsigncode sign -pkcs11module ./libssign_pkcs11.so -pkcs11cert 'pkcs11:type=cert' -h sha256 -t http://time.certum.pl -in app.msi -out app-signed.msi
签名卡住、无确认推送
原因:Agent 锁屏、SimplySign 客户端退出、账号掉线
对策:Windows 构建机配置永不锁屏,开机自启 SimplySign,保持托盘常驻
证书找不到
优先使用指纹 /sha1,OV/EV 重签之后名称不变,但指纹会变;重签后记得更新脚本内指纹
时间戳报错
服务器防火墙拦截 time.certum.pl,或者 DNS 解析异常;单独测试 curl http://time.certum.pl
多次弹 App 确认
不要循环里单独起 signtool 进程;把一批文件放在同一个脚本循环内,属于同一个会话,只确认一次
额度超限
OV/EV 云签共享每月 5000 次,超过之后签名返回失败,次月重置
OV 尝试签驱动
直接报错,证书权限不支持;驱动 / WHQL 必须换成 EV 云签证书,脚本不用改
无人值守需求
默认模式必须人工 App 确认;大批量可信流水线,可以向代理商申请 SimplySign 预授权模式,配置白名单 IP / 机器,免二次确认(合规管控严格,不是默认开通)
普通桌面软件、小工具、插件、VBA 宏、CI 自动化,预算优先 → Certum OV 云签
需要驱动开发、WHQL 认证、面向 C 端大规模分发,想要减少 SmartScreen 警告 → Certum EV 云签
内网完全离线打包、不能联网 → 放弃云签,选择 Certum 硬件 Token 版代码签名
Linux 为主构建集群,不想维护 Windows 机器 → 不推荐 SimplySign 云签方案