使用signtool.exe自动执行代码签名,但不存储证书或密码

时间:2014-09-29 16:47:53

标签: c# visual-studio-2013 code-signing signtool

我在Visual Studio 2013中有一个C#/ .NET 4.5 x64项目。不止一个开发人员在这个项目上工作,因此代码在Git中管理。我正在使用.dll对已编译的.exesigntool.exe进行签名。我的公司购买了代码签名证书,如果我从命令行手动签名,如下所示:

signtool.exe sign /f cert.p12 /p "password" "compiled.dll"

...然后看起来一切都很棒:我得到了一条成功消息,Windows资源管理器中已编译DLL的属性显示为正确签名。所以,我对实际的签名过程没有任何问题。

但是,证书及其密码不得存在于Git 中。它们将在项目的所有开发人员之外提供。我可以假设每个开发人员在构建项目时都会将证书存储在他计算机上的预定位置,并且他知道密码。

所以,这就是我的问题:如何配置Visual Studio 2013以自动签署其编译输出,而无需在Git中保留证书或密码?我希望它如此简单因为,一旦开发人员在预定义的路径(或导入的,或其他)中拥有证书,并且假设开发人员知道证书的密码,那么点击" Build"在Visual Studio 2013中,只需构建并签名,不会有任何问题。

如果签名过程可以是非交互式的(没有密码提示),那就是奖金。最终,这将成为可能对其输出进行签名的持续集成(CI)服务器的一部分,并且由于它是自动化的,因此没有人会输入密码。但是,我现在要采取任何解决方案。

我的证书是PKCS#12格式,并受密码保护。 Windows声称它没有标记为导出。

7 个答案:

答案 0 :(得分:13)

我之前使用的解决方案类似于@Mikko的答案,但它分为两部分:

  1. 一个本地非受控脚本,它只设置一个包含密码的环境变量。这是您为每个开发人员提供的文件。

    @echo off
    set SIGNPASS=whatever
    
  2. 源代码控制的脚本,它调用前一个脚本并执行实际签名。

    @echo off
    setlocal
    call "C:\local\signing_password.bat"
    "C:\toolpath\signtool.exe" sign /f "c:\certpath\cert.p12" /p "%SIGNPASS%" "%1"
    endlocal
    
  3. setlocal / endlocal对确保在手动运行脚本时密码不会泄漏到环境中。

    "%1"是在Post Build步骤中作为脚本参数传递的可执行文件的路径。 ..

答案 1 :(得分:7)

另一种方法是在每个开发人员私有证书存储中导入证书,然后像这样使用带有signtool的指纹:

(A OR B) AND (NOT C)

(A OR (C AND D)) AND (NOT (F OR G))

然后在初始导入证书时只需要密码,而不是在构建期间。

答案 2 :(得分:3)

您可以在项目目录中添加batch文件,例如sign.bat

@echo off
<path>\signtool.exe /f cert.p12 /p "password" "compiled.dll"
echo Signed with certificate

将文件添加到.gitignore,但不要将其添加到Visual Studio项目中。

在项目的属性中,将batch称为构建后事件。

enter image description here

答案 3 :(得分:1)

作为这些的新替代方案,我创建了一个代码签名服务,个人和组织可以将其部署到Azure环境中,这有助于自动执行代码签名,同时确保私钥永远不会离开Key Vault的HSM。

详情见项目页面:https://github.com/onovotny/SignService

答案 4 :(得分:0)

当我使用"$(SIGNPASS)"格式提供密码时,从VS2015调用 signtool 对我不起作用,但是当您使用符号"%SIGNPASS%"时,它无法正常工作。

检查在VS输出窗口中如何形成完整的signtool命令,命令看起来是一样的,但是有些不同。

请记住双引号路径以保护自己免受包含空格的路径的影响。

答案 5 :(得分:0)

我无法添加DanielSchlößer的答案 - 在我看来,这确实是最好的答案。将证书添加到证书存储区后,签名不需要密码和pfx。

但是我想添加以下注释:

  1. 证书必须正确安装在证书存储区中(我使用.pfx和密码)
  2. signtool.exe必须支持/ sha1命令行选项(我正在使用10.0.16299)
  3. 对于我的证书,我花了很长时间才意识到我需要使用/ sm开关来指定'机器商店'而不是'用户商店'
  4. 指纹可在证书属性
  5. 的详细信息选项卡中找到
  6. 尽管我读过另一篇文章,但Thumbprint哈希不区分大小写
  7. 所以这是我的命令行,适用于SHA256(哈希已被更改):

    signtool.exe sign /sm /debug /v /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /sha1 65cc2e77dc52b99d46e7caae2377bb5d7d9384b2 "D:\app.msi"
    

答案 6 :(得分:0)

将证书保存在Windows证书存储区中,并使用signtool.exe / n加载它... https://docs.microsoft.com/en-us/windows/win32/seccrypto/using-signtool-to-sign-a-file