【问题标题】:Signing a ClickOnce application with an AfterCompile target使用 AfterCompile 目标对 ClickOnce 应用程序进行签名
【发布时间】:2017-01-12 16:53:19
【问题描述】:

一周以来,我一直在努力思考Authenticode certificates。我从 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>

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

"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 过滤器标记,从而使整个过程变得毫无意义。我该如何解决这个问题?

更新:在阅读this guide 之后,似乎即使我正确地签署了东西,我仍然可能因为我的应用程序没有足够的“声誉”而碰到 SmartScreen 过滤器。但是,我想确认我一开始就正确签署了文件,而不是在追烟。 (或者,如果这表明构建过程出现故障,我想纠正它!)

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

编译后:

"signtool.exe" 签名 /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" 签名 /f "MyCoolApp lication\certificate.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

_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

CopyFilesToOutputDirectory:

将文件从“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

【问题讨论】:

  • 我的经验是您需要一个扩展验证 (EV) 代码签名证书才能通过 SmartScreen(更昂贵...)。我们有一个使用此类证书签名的 click once 应用程序,它工作正常(我们没有像您那样使用 signtool 的自定义步骤,我们只是使用常规的 VS 项目 ClickOnce 属性对其进行签名)。缺点是您无法使用 pfx 和密码自动执行此操作:stackoverflow.com/questions/17927895/…
  • @SimonMourier 我知道 EV 证书的优势。但是,从 Microsoft 网站看来,即使标准(非 EV)CSC 没有带来即时完美声誉的好处,它仍然比未签名代码更快地建立声誉,并且声誉建立在您的发布者名称而不是单个应用程序(就像使用未签名代码一样)。是的,不如 EV 理想,但是 EV 除了成本之外还有其他缺点——比如你不能虚拟化你的构建服务器,因为你需要附加硬件加密狗来签名。
  • 不过,我的问题更多是关于在我设置完成签名的“AfterCompile”目标之后,MSBuild 中的某些内容似乎在默默地更改/重新签署我的可执行文件,以及我该如何解决这个问题。如果正如我所怀疑的那样,过程中的某些东西意外地更改了文件,我想无论我的 CSC 是否包含 EV,我都会受到这个问题的困扰。
  • 关于 EV,我同意它完全同意它是否需要它不是很清楚,无论如何,我可以在另一台服务器托管的虚拟机中成功构建它(我通过远程桌面连接, EV 证书驻留在一个成功跨越边界的 USB 密钥中,前提是我的机器和我猜的 VM 上都安装了 SafeNet 客户端)。我不清楚为什么您需要自定义步骤来使用 ClickOnce 对您的应用进行签名。
  • 检查我的更新答案

标签: c# msbuild clickonce code-signing signtool


【解决方案1】:

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

这是我的构建顺序:

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

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

成功签名的文件数:1

警告:0

错误数:0

"signtool.exe" 签名 /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 是使用 /as 键完成的 - 附加签名的选项。

因此,如果您想保留自定义签名命令,则应禁用“签署 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>

【讨论】:

  • (1.) 我的构建输出与您发布的几乎相同。 (2.) 没有错误。 (3.) 两个EXE的文件修改时间确实是一样的。但是,如果我查看其属性的“数字签名”选项卡,它就像我在上面发布的图片一样,其中一个有 2 个带时间戳的签名,另一个有 1 个没有时间戳的签名。 (4.) 它们的文件大小相差约 7 KB。
  • /as 选项无效,signtool.exe from \Microsoft SDKs\Windows\v7.1\Bin
【解决方案2】:

在项目属性中检查“签署程序集”和“签署 ClickOnce 清单”最终会导致执行 signtool.exe(通过 SignFile MSBuild 任务),我觉得这可能与您的 Exec 冲突任务,由于冗余和/或signtool.exe 版本的差异,两个路径执行。一次尝试以下修改(显然跳过您已经尝试过的任何修改)。

  • 取消选中项目属性中的“签署程序集”和“签署 ClickOnce 清单”。
  • 仅选中“签署 ClickOnce 清单”。
  • 只勾选“签署程序集”。
  • 注释掉您的 AfterCompile 目标并选中“签署 ClickOnce 清单”。
  • 注释掉您的 AfterCompile 目标并选中“签署程序集”。
  • 注释掉您的 AfterCompile 目标并选中“签署程序集”和“签署 ClickOnce 清单”
  • 将您的命令更改为以下命令并尝试使用上述排列:"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /target:Publish /p:Configuration=Release /p:Platform=AnyCPU /p:TargetFrameworkSDKToolsDirectory="C:\Program Files (x86)\Windows Kits\8.1\bin\x64\" MyCoolApplication.csproj

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 2010-10-27
    • 1970-01-01
    • 2018-06-26
    • 2012-04-05
    相关资源
    最近更新 更多