Windows 中如何正确注册签名服务

关于在 windows 服务中注册自定义服务,遇到的问题及解决思路。

问题背景

Windows 服务的默认登录身份是本地系统账户LocalSystem,而 vsign 签名鉴权基于当前账户的证书池。所以在服务中调用 vsign 签名时,无法找到操作员证书进行无法签名成功,如下图所示:

登录用户信息
登录用户信息
签名失败
签名失败

方案一

考虑将服务登录账户变更为操作员证书所在账户,变更方式如下:右键服务 -> 属性 ->登录选项卡 -> 此账户(输入账户名称),见下图:

更改登录用户
更改登录用户

方案二

考虑在服务签名时单独以操作员所在账户调用 VSign 签名,使用 windows 官方工具 RunasPsExec

Runas,允许用户以与当前登录提供的权限不同的权限运行特定的工具和程序。由于 Runas 不支持使用 password 参数且不支持管道传输密码,所以需要人为的输入密码才能成功切换账户。所以不适宜服务签名。

参考示例:

cmd := exec.Command("runas",
    `/user:domain\user`,
    `/path/to/ssigncode.exe`,
    "sign -s ssigncode.com:8080",
    "-i C:\Users\rango\Downloads\python-2.7.amd64.msi",
    "-o C:\Users\rango\Downloads\python-2.7.amd64_signed.msi",
    "--cert_hash", "/sha1/of/certificate")
// 需要手动输入密码。

PsExec,一种轻巧的 telnet 替代品,支持在其他系统上执行进程,并为控制台应用程序提供完整的交互性,而无需手动安装客户端软件。 该工具支持 -p 参数,调用代码如下:

cmd := exec.Command(`C:\Users\rango\Downloads\PSTools\PsExec.exe`,
    `\\laptop-q979ofoa`, // 域名称
    "-u", "UserName", // 账户名称
    "-p", "Password", // 账户口令
    "-h",
    `C:\Users\rango\Downloads\ssigncode.exe`,
    "sign", "-s", "ssigncode.com:8080", "-i", `C:\Users\rango\Downloads\python-2.7.amd64.msi`, 
    "-o", `C:\Users\rango\Downloads\ooo.msi`,
    "--cert_hash", "34FA7A166706C3A9C7908C4C43B053E06B8F3324")

最终结果如下:

签名成功
签名成功

参考链接

  • 如何使用 golang 注册服务?https://github.com/kardianos/service

  • 使用工具 InstSrv 注册自定义服务?https://support.microsoft.com/en-us/help/137890/how-to-create-a-user-defined-service