使用 AfterCompile 目标签署 ClickOnce 应用程序

soa*_*gem 5 c# msbuild clickonce code-signing signtool

一周以来,我一直在努力思考Authenticode 证书。我从 Comodo 购买了一个 CSC,我有一个 ClickOnce 应用程序,我想签名以便 SmartScreen 过滤器警告消失。

我的应用程序程序集是强命名的,我在我的项目属性中勾选了“签署程序集”框。我还在同一项目属性中勾选了“签署 ClickOnce 清单”的框。最后,我在我的项目文件中将以下执行设置为 AfterCompile 目标,以便使用 SHA1 和 SHA256 对可执行文件进行双重签名:

<Target Name="AfterCompile">
  <Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /t http://timestamp.comodoca.com /v &quot;$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)&quot;" />
  <Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /as /v &quot;$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)&quot;" />
</Target>
Run Code Online (Sandbox Code Playgroud)

然后我运行以下命令来发布项目:

"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /target:Publish /p:Configuration=Release /p:Platform=AnyCPU MyCoolApplication.csproj

我注意到这个命令最终会创建三个独立版本的 MyCoolApplication.exe:

  • 它在 bin\Release 中构建一份未签名的副本
  • 它在 obj\Release 中构建了另一个副本,该副本是双重签名的
  • 它在 bin\Release\app.publish 中构建了一个最终副本,该副本仅签名一次并且似乎缺少时间戳

不幸的是,需要工作的是 bin\Release\app.publish 中的副本,但由于某种原因,此版本正在删除双重签名。我的理解——这可能是错误的——是它在 obj\Release 中构建东西,将它们复制到 bin\Release\app.publish,然后签署清单。然而,很明显其他事情正在发生,因为最终可执行文件上的数字签名显然已更改。这是并排的这两个文件的属性:

双重签名 单签,无时间戳

最终单签名/缺失时间戳版本的问题是应用程序仍然被 SmartScreen 过滤器标记,使整个过程变得毫无意义。我怎样才能解决这个问题?

更新:阅读本指南后,似乎即使我正确签名,由于我的应用程序没有足够的“声誉”,我仍然可能会遇到 SmartScreen 过滤器。但是,我想确认我首先正确地签署了东西,并且不是在追逐烟雾。(或者,如果这表明构建过程出现故障,我想纠正它!)

编辑:这是@CodeFuller 要求的 MSBuild.exe 输出的结尾:

编译后:

"signtool.exe" sign /f "certificate.pfx" /p mypassword /t http://timestamp.comodoca.com /v "MyCoolApplication\obj\Release\MyCoolApplication.exe"

选择了以下证书:

...

完成添加额外的商店

签名成功:MyCoolApplication\obj\Release\MyCoolApplication.exe

成功签名的文件数:1

警告数:0

错误数:0

"signtool.exe" sign /f "MyCoolApp lication\certificate.pfx" /p mypassword /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /as /v "MyCoolApplication\obj\发布\MyCoolApplication.exe”

选择了以下证书:

...

完成添加额外的商店

签名成功:MyCoolApplication\obj\Release\MyCoolApplication.exe

成功签名的文件数:1

警告数:0

错误数:0

_DeploymentComputeClickOnceManifestInfo:

创建目录“bin\Release\app.publish”。

将文件从“obj\Release\MyCoolApplication.exe”复制到“bin\Release\app.publish\MyCoolApplication.exe”。

_CopyAppConfigFile:

将文件从“App.config”复制到“bin\Release\MyCoolApplication.exe.config”。

_CopyManifestFiles:

将文件从“obj\Release\MyCoolApplication.exe.manifest”复制到“bin\Release\MyCoolApplication.exe.manifest”。

MyCoolApplication -> C:\Users\Gordon\Documents\Visual Studio 2015\Projects\MyCoolApplication\MyCoolApplication\bin\Release\MyCoolApplication.exe.manifest

将文件从“obj\Release\MyCoolApplication.application”复制到“bin\Release\MyCoolApplication.application”。

MyCoolApplication -> C:\Users\Gordon\Documents\Visual Studio 2015\Projects\MyCoolApplication\MyCoolApplication\bin\Release\MyCoolApplication.application

复制文件到输出目录:

将文件从“obj\Release\MyCoolApplication.exe”复制到“bin\Release\MyCoolApplication.exe”。

MyCoolApplication -> C:\Users\Gordon\Documents\Visual Studio 2015\Projects\MyCoolApplication\MyCoolApplication\bin\Release\MyCoolApplication.exe

将文件从“obj\Release\MyCoolApplication.pdb”复制到“bin\Release\MyCoolApplication.pdb”。

_CopyFilesToPublishFolder:

创建目录“bin\Release\app.publish\Application Files\MyCoolApplication_1_0_0_0”。

将文件从“bin\Release\MyCoolApplication.exe.manifest”复制到“bin\Release\app.publish\Application Files\MyCoolApplication_1_0_0_0\MyCoolApplication.exe.manifest”。将文件从“bin\Release\app.publish\MyCoolApplication.exe”复制到“bin\Release\app.publish\Application Files\MyCoolApplication_1_0_0_0\MyCoolApplication.exe.deploy”。将文件从“App.config”复制到“bin\Release\app.publish\Application Files\MyCoolApplication_1_0_0_0\MyCoolApplication.exe.config.deploy”。将文件从“triforce.ico”复制到“bin\Release\app.publish\Application Files\MyCoolApplication_1_0_0_0\triforce.ico.deploy”。完成构建项目“C:\Users\Gordon\Documents\Visual Studio 2015\Projects\MyCoolApplication\MyCoolApplication\MyCoolApplication.csproj”

构建成功。0 警告 0 错误

已用时间 00:00:06.53

Cod*_*ler 5

您期望二进制文件是内置的obj\Release然后复制到bin\Release\app.publish. 对于我的测试项目,AfterCompile目标的自定义步骤相同,一切都按预期工作。所以很可能在构建过程中出现问题。如需进一步调查,请使用输出更新您的问题MSBuild.exe

这是我的构建顺序:

AfterCompile:
"signtool.exe" sign /f "MyKey.pfx" /p mypassword /t http://timestamp.comodoca.com /v "MyCoolApplication\obj\Release\MyCoolApplication.exe"
...

签名成功:MyCoolApplication\ obj\Release\MyCoolApplication.exe

成功签名的文件数:1

警告数:0

错误数:0

“signtool.exe” sign /f “MyKey.pfx” /p mypassword /fd sha256 /tr http://timestamp .comodoca.com/?td=sha256 /td sha256 /as /v "MyCoolApplication\obj\Release\MyCoolApplication.exe"
...

成功签名:MyCoolApplication\obj\Release\MyCoolApplication.exe

成功签名的文件数:1

警告数:0

错误数:0

CleanPublishFolder:
正在删除目录“bin\Release\app.publish\”。
_DeploymentComputeClickOnceManifestInfo:
创建目录“bin\Release\app.publish”。
将文件从“obj\Release\MyCoolApplication.exe”复制到“bin\Release\app.publish\MyCoolApplication.exe”。
...
构建成功。
0 警告
0 错误

在此处输入图片说明

所以我会继续回答以下问题:

  • 您的 MSBuild 输出包含相同的序列还是不同?
  • 输出是否包含一些错误?
  • 构建后,obj\Release\MyCoolApplication.exeRelease\app.publish\MyCoolApplication.exe文件的时间戳是否相等?
  • 这些文件的内容相同还是不同?

更新:

启用构建输出的诊断详细程度后,所有内容都清除了一点。

在项目设置的签名选项卡上启用“签署 ClickOnce 清单”会导致SignTool.exe调用bin\Release\app.publish\MyCoolApplication.exe. 默认情况下,SignTool 将覆盖现有签名。这就是为什么在 AfterCompile 目标中第二次调用 SignTool 是使用/askey完成的- 用于附加签名的选项。

因此,如果您想保留自定义签名命令,则应禁用“签署 ClickOnce 清单”选项并添加用于签署清单的自定义命令。要完成此操作,应在以下构建步骤中签署以下文件:

之后_DeploymentComputeClickOnceManifestInfo的目标: bin\Release\app.publish\MyCoolApplication.exe。文件名的宏是"$(PublishDir)$(TargetFileName)"

之后_DeploymentSignClickOnceDeployment的目标: bin\Release\app.publish\Application Files\MyCoolApplication_1_0_0_3\MyCoolApplication.exe.manifest- "$(_DeploymentApplicationDir)$(_DeploymentTargetApplicationManifestFileName)" bin\Release\app.publish\MyCoolApplication.application- "$(PublishDir)$(TargetDeployManifestFileName)" bin\Release\app.publish\setup.exe-$(PublishDir)\setup.exe

清单应使用mage.exe工具签名。

这是更新的项目文件,可满足您的需求:

<Target Name="AfterCompile">
<Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /t http://timestamp.comodoca.com /v &quot;$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)&quot;" />
<Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /as /v &quot;$(ProjectDir)obj\$(ConfigurationName)\$(TargetFileName)&quot;" />
</Target>

<Target Name="SignAssembly" AfterTargets="_DeploymentComputeClickOnceManifestInfo">
<Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /t http://timestamp.comodoca.com /v &quot;$(PublishDir)$(TargetFileName)&quot;" />
<Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /as /v &quot;$(PublishDir)$(TargetFileName)&quot;" />
</Target>

<Target Name="SignManifest" AfterTargets="_DeploymentSignClickOnceDeployment">
<Exec Command="&quot;c:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\mage.exe&quot; -Sign &quot;$(_DeploymentApplicationDir)$(_DeploymentTargetApplicationManifestFileName)&quot; -CertFile &quot;$(ProjectDir)certificate.pfx&quot; -Password mypassword -TimeStampUri http://timestamp.comodoca.com" />
<Exec Command="&quot;c:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\mage.exe&quot; -Sign &quot;$(PublishDir)$(TargetDeployManifestFileName)&quot; -CertFile &quot;$(ProjectDir)certificate.pfx&quot; -Password mypassword -TimeStampUri http://timestamp.comodoca.com" />
<Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /t http://timestamp.comodoca.com /v &quot;$(PublishDir)\setup.exe&quot;" />
<Exec Command="&quot;C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe&quot; sign /f &quot;$(ProjectDir)certificate.pfx&quot; /p mypassword /fd sha256 /tr http://timestamp.comodoca.com/?td=sha256 /td sha256 /as /v &quot;$(PublishDir)\setup.exe&quot;" />
</Target>
Run Code Online (Sandbox Code Playgroud)