使用Signtool与Google KMS签名带VBA的Excel文件遇问题
解决Google KMS HSM结合Signtool签名带VBA宏Excel文件的问题
问题场景
已实现通过Google KMS HSM存储私钥,结合Signtool与CNG 1.2正常签名exe、dll文件,命令示例:
"signtool.exe" sign /v /fd sha256 /tr http://timestamp.digicert.com /td sha256 /csp "Google Cloud KMS Provider" /kc "projects/*/keyRings/*/cryptoKeys/*/cryptoKeyVersions/1" /f "c:\test.crt" /ac "c:\test_DigiCertCA.crt" "c:\temp\test.exe"
但签名带VBA宏的xlsm文件时出现异常:
- 32位Signtool提示
No private key is available,无法识别KMS密钥 - 64位Signtool报错
Signtool Error: An unexpected internal error has occurred. Error information: Could not associate private key with certificate.(错误码0x80070005)
已完成前置操作:添加SIP、将证书导入本地机器/个人账户存储、通过certutil -f -csp "Google Cloud KMS Provider" -repairstore My "证书指纹"关联证书与KMS私钥、配置服务账号KMS权限及GOOGLE_APPLICATION_CREDENTIALS环境变量。
排查与解决步骤
1. 确保32位CNG Provider正确安装注册
Office及VBA宏签名默认依赖32位组件,即使系统是64位,也需确认32位Google Cloud KMS CNG Provider已部署:
- 下载与当前64位版本匹配的32位CNG Provider安装包并执行安装
- 运行以下命令验证32位注册表项存在:
reg query HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography\Defaults\Provider\Google Cloud KMS Provider
2. 针对不同位数环境重新关联证书与私钥
避免混合使用本地机器和个人账户存储,优先使用本地机器存储,并分别用对应位数的certutil执行关联:
- 64位环境(System32目录):
C:\Windows\System32\certutil.exe -f -csp "Google Cloud KMS Provider" -repairstore My "9476686976D80B24356077B688789537F1237797" - 32位环境(SysWOW64目录):
C:\Windows\SysWOW64\certutil.exe -f -csp "Google Cloud KMS Provider" -repairstore My "9476686976D80B24356077B688789537F1237797"
3. 简化Signtool命令参数
签名xlsm时,/kc和/sha1参数同时指定可能导致冲突,建议仅保留/sha1让系统自动匹配关联的KMS私钥:
- 64位Signtool命令:
signtool.exe sign /v /debug /csp "Google Cloud KMS Provider" /sha1 9476686976D80B24356077B688789537F1237797 /ac "c:\test_DigiCertCA.crt" /fd sha256 /tr http://timestamp.digicert.com /td sha256 "c:\temp\1.xlsm" - 32位Signtool命令(需调用对应路径的32位程序):
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\signtool.exe" sign /v /debug /csp "Google Cloud KMS Provider" /sha1 9476686976D80B24356077B688789537F1237797 /ac "c:\test_DigiCertCA.crt" /fd sha256 /tr http://timestamp.digicert.com /td sha256 "c:\temp\1.xlsm"
4. 同步32位环境的权限与环境变量
32位进程无法直接读取64位系统级环境变量,需在32位命令提示符中手动设置:
set GOOGLE_APPLICATION_CREDENTIALS=C:\path\to\your\service-account-key.json
同时确认服务账号已拥有cloudkms.cryptoKeyVersions.signAsymmetric权限,且目标KMS密钥版本处于启用状态。
5. 验证Office宏签名配置
- 打开Excel,依次进入「文件」→「选项」→「信任中心」→「信任中心设置」→「宏设置」,勾选「信任发布者的宏」,并确认证书已添加到「受信任的发布者」列表
- 尝试通过Excel「开发工具」→「数字签名」手动选择证书签名,若能成功则排除Signtool参数问题
额外注意事项
- 保持Google Cloud KMS CNG Provider为最新版本,旧版本可能存在VBA签名兼容性缺陷
- 签名前确保xlsm文件未被打开,避免文件占用导致签名失败
内容的提问来源于stack exchange,提问作者Keoshz




