15

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

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

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

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

所以,这是我的问题:如何配置 Visual Studio 2013 以自动签署其编译输出而不在 Git 中保留证书或其密码?我希望它尽可能简单,一旦开发人员在预定义的路径(或导入,或其他)中拥有证书,并假设开发人员知道证书的密码,在 Visual Studio 中单击“构建” 2013 只是构建并签署它,没有提出任何问题。

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

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

4

6 回答 6

14

我之前使用过的解决方案类似于@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
    

setlocal/对确保在endlocal手动运行脚本时密码不会泄漏到环境中。

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

于 2014-09-30T00:46:38.253 回答
14

另一种方法是在每个开发人员的私有证书存储中导入证书,然后将指纹与 signtool 一起使用,如下所示:

signtool ... /sha1 'hex thumbprint' ...

那么您只需要在证书的初始导入期间而不是在构建期间需要密码。

于 2017-03-17T11:20:10.337 回答
7

我无法补充 Daniel Schlößer 的答案——在我看来,这确实是最好的答案。将证书添加到证书存储后,就不需要密码和 pfx 进行签名。

但是我想添加以下评论:

  1. 证书必须正确安装在证书存储中(我使用了 .pfx 和密码)
  2. signtool.exe 必须支持 /sha1 命令行选项(我使用的是 10.0.16299)
  3. 对于我的证书,我花了很长时间才意识到我需要使用 /sm 开关来指定“机器存储”而不是“用户存储”
  4. 指纹位于证书属性的详细信息选项卡中
  5. 尽管我阅读了另一篇文章,但指纹哈希不区分大小写

所以这是适用于 SHA256 的命令行(哈希已更改):

signtool.exe sign /sm /debug /v /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /sha1 65cc2e77dc52b99d46e7caae2377bb5d7d9384b2 "D:\app.msi"
于 2018-04-20T22:03:11.863 回答
3

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

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

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

在项目的属性中,调用batchas post-build 事件。

在此处输入图像描述

于 2014-09-29T18:02:51.550 回答
2

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

详细信息在此处的项目页面上:https ://github.com/onovotny/SignService

于 2018-01-07T14:59:43.933 回答
0

当我在表单中提供密码时,从 VS2015调用signtool对我不起作用,"$(SIGNPASS)"但是当您使用符号时它确实起作用"%SIGNPASS%"

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

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

于 2015-12-21T23:21:05.783 回答