Certum SimplySign OV / EV 云签 + CI/CD 集成完整科普
本文面向开发、运维、打包负责人,兼顾原理、差异、选型、落地脚本、坑点,适合放在知识库、内部文档,也可用于对外科普。 核心前提:Certum SimplySign 是 Certum 官方的云端 HSM 代码签名方案,无实体 U 盾,私钥全程托管在符合 FIPS 140-2 Level 3 的云端密码机,私钥无法导出,满足当前 CA/B 论坛对代码签名密钥硬件保护的强制要求。 时间戳统一地址:
http://time.certum.pl,固定 SHA256。
一、先分清:Certum OV 云签 和 EV 云签(SimplySign)
很多人以为只是价格差别,实际是验证等级、证书能力、使用边界完全不同。
1. Certum OV SimplySign(组织验证云签)
✅ 定位:企业商用普通代码签名,性价比款
✅ 验证方式:组织信息核验(营业执照、工商公示信息、电话回拨核验企业)
✅ 签名对象:.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,禁止商用闭源软件,只适合开源项目发布。
2. Certum EV SimplySign(扩展验证云签)
✅ 定位:高信任等级代码签名,驱动、WHQL、高安全分发可选方案 ✅ 验证方式:EV 增强深度核验,除企业资质,额外核验企业实际经营地址、负责人、控制权,审核更严格、周期略长 ✅ 签名对象:普通程序 + Windows 内核驱动.sys,支持 WHQL 提交、Office 宏大规模分发 ✅ 优势
微软信任等级更高,自带初始信誉,SmartScreen 警告更少,用户侧体验更好
可以直接用于驱动签名、WHQL 流程,这是 OV 云签做不到的核心差异
和 OV 云签共用一套 SimplySign 客户端、一套签名命令、一套 CI 脚本,集成方式完全一致,只是证书权限不同 ⚠️ 同样限制:每月 5000 签名上限、必须联网签名、私钥不可导出
OV 云签 vs EV 云签 精简对比表
表格
| 项目 | 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 云签底层工作原理(理解这个,才能看懂 CI 为什么这么写)
证书申请通过后,在 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。
三、前置环境准备(所有 CI 脚本共用的前置条件)
无论 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 托盘进程,锁屏会导致客户端断开,签名卡住
四、全套 CI/CD 集成脚本模板(OV、EV 通用,证书切换只改证书名称 / 指纹)
重点:OV 和 EV 脚本命令完全一模一样,只需要替换证书名称或者指纹,不需要改签名逻辑
模板 1:BAT 批处理脚本(Jenkins Windows Agent、本地打包)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
模板 2:PowerShell 脚本(推荐,Azure DevOps、Jenkins 可选方案)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 Green模板 3:Jenkins Pipeline(Windows Agent)
pipeline {
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是否确认、网络连通性"
}
}
}模板 4:GitHub Actions(仅自托管 Windows Runner,公有托管 Runner 不适合)
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/
模板 5:PowerShell 脚本签名 PS1 脚本(Authenticode 签名)
$cert = Get-ChildItem Cert:CurrentUserMy -CodeSigningCert | Where-Object {$_.Subject -match "你的公司全称"}
Set-AuthenticodeSignature -FilePath ".deploy.ps1" -Certificate $cert -TimestampServer "http://time.certum.pl" -HashAlgorithm SHA256Linux 补充(仅了解,非官方方案)
osslsigncode sign -pkcs11module ./libssign_pkcs11.so -pkcs11cert 'pkcs11:type=cert' -h sha256 -t http://time.certum.pl -in app.msi -out app-signed.msi
五、常见坑与运维注意事项(CI 场景高频问题)
签名卡住、无确认推送
原因: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 云签方案