始终签署可执行文件(exe,dll,ocx等)是一种很好的做法.另一方面,对于开源项目,可能会考虑忽视所有其他开发人员对项目的贡献.
这对我来说是一个非常道德的困境,我希望从处于类似情况的人或者为开源项目做出贡献的人那里听到更多关于此的意见.
我想请注意,这个问题是针对使用.NET 4用C#编写的开源项目,因此当用户单击可执行文件时,系统会提示他或她发出警告,指出该文件来自不受信任的发布者,如果它没有经过数字签名.
顺便说一下,程序集都已经具有强命名(签名),但它们尚未进行数字签名(即使用Verisign代码签名证书).
我尝试在安装了 VS2010 的 Windows Server 2008 R2 x64 上使用新的代码签名证书对 .NET 应用程序进行authenticode 签名,但 SignTool 始终响应“访问被拒绝”:
SignTool.exe sign /v /a /sha1 <thumbprint> MyApplication.exe
The following certificate was selected:
Issued to: <redacted>
Issued by: VeriSign Class 3 Code Signing 2010 CA
Expires: Thu Jun 28 01:59:59 2012
SHA1 hash: <thumbprint>
Done Adding Additional Store
SignTool Error: Access is denied.
SignTool Error: An error occurred while attempting to sign: MyApplication.exe
Number of files successfully Signed: 0
Number of warnings: 0
Number of …
Run Code Online (Sandbox Code Playgroud) 我们最近购买了代码签名证书,并且我已将代码签名步骤合并到我们的自动化构建中。
我们的构建脚本必须构建 VB6 和 .NET 项目,因此我们目前有一个可以构建所有内容的批处理文件。对于 .NET 项目,我们的构建脚本调用 MSBUILD,传入要构建的解决方案文件。这些解决方案中的项目具有一些第三方依赖项,并且这些文件都在References中打开了Copy Local选项,因为运行应用程序需要它们。此外,某些项目使用 COM Interop,因此它们具有自动生成的 Interop 程序集(例如Interop.MSXML2.dll),这些程序集也会在生成期间复制到输出文件夹。
我试图找出一种简单的方法来对构建过程中编译的文件(即我们的程序集)进行代码签名,并忽略第三方库和互操作程序集,而无需分别在每个程序集上调用signtool.exe。
目前,我通过在构建脚本中执行以下操作来解决此问题:
lib
文件夹中,因此我将所有文件从lib
回复制到构建输出文件夹中,覆盖构建复制到那里的副本。这样这些文件就不再被签名,但我们的程序集仍然是我的问题是,有更好的方法吗?我能想到的唯一的其他选择是在每个需要签名的程序集上单独调用signtool.exe,但这可能会很痛苦,因为项目的数量和其中发生的更改量(程序集被重命名、移动、获取)随着项目的发展而删除)。另外,我不想猜测特定程序集是否已签名,因此循环遍历文件并批量签名对我来说最有意义。
然而,与此同时,任意签署我们没有使用代码签名证书创建的文件似乎并不正确(在道德上、法律上或其他方面)。
或者也许我完全以错误的方式处理这个问题?
我需要SignerInfo
从Authenticode
ASN1 结构中的数字签名 PE 文件中提取。
INFO
:PE 文件包含由Security Directory RVA
inside指定的偏移量处的验证码Optional Header Data Directories
。我曾尝试在阅读Microsoft Authenticode PE 签名格式提供的文档后开始,但没有运气,因为我对 SSL/TSL 非常陌生。
我的问题:
有没有办法解析二进制文件并以 C 字符串格式打印数据结构?
有什么方法可以解析给定的二进制文件并指向SignerInfo
or SignerName
?
NOTE
:我不想使用任何平台相关的 API,因为我希望代码与平台无关。
提前感谢所有大师:-)
UPDATE:
我在 C# 中找到了一个代码。有人能帮我找到相同的 C 语言吗?
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography.X509Certificates;
public class CertInfo
{
public static void Main(String[] args)
{
byte[] certBytes;
X509Certificate x509cert;
while (true)
{
Console.WriteLine("\nEnter File Name: ");
String filename = Console.ReadLine();
if …
Run Code Online (Sandbox Code Playgroud) 我有一个 .NET 程序集,我对其进行了强命名,并将其放入 GAC 中。.pfx
但是,稍后还会使用文件对同一程序集进行数字签名,以进行数字签名。
我注意到这个经过双重签名的程序集未通过强名称验证,并且不会安装在目标计算机的 GAC 中。
数字签名过程是否有可能删除 SN 密钥生成的强命名过程?
数字签名是必不可少的,如果两者不兼容,那么文件可以由数字签名吗?.pfx
像 SN 命名过程一样简单地由文件对文件进行签名?
另外,程序集位于C++/CLI
,而不是C#
。
编辑:查看MSDN 文档,它说是否使用链接器选项进行强命名,以及是否使用像这样的后处理工具mt.exe
(我不确定是否Signtool.exe
属于这些工具),则需要重新签署程序集。
另外,这个声明:
如果在开发环境中生成时使用签名属性,则可以通过在生成后事件中显式调用 sn.exe(Sn.exe(强名称工具))来成功对程序集进行签名。
...有点令人困惑。它指的是哪些属性,CLR
属性还是Linker
选项?
我们将可执行文件交付给客户端服务,该服务在从我们的服务器下载该可执行文件后在新进程中启动该可执行文件。
可执行文件已使用我们公司的 CodeSigning-Certificate 进行签名(验证码),现在我想验证下载的可执行文件是否使用此 CodeSigning-Certificate 进行了有效签名,以防止恶意的中间人攻击。
但目前我找不到任何关于如何在不使用“signtool.exe”(客户端不可用)的情况下验证这一点的提示。
客户端上的下载服务是一个用 C# 编写的 .NET 4.0 应用程序。所以我正在寻找一种方法来验证下载文件的验证码,并且只有在验证成功时才继续。
在 Windows 10 的“快速环”上,我在自己的安装可执行文件上出现了奇怪的行为:
多年来,我一直使用Authenticode对它们进行 SHA-1 签名,而且从未遇到任何问题。
最近 Windows 10 无法识别我的(有效)签名。
当从我的网站下载 setup.exe 并执行它时,Windows SmartScreen 消息框出现并告诉我:
...
发布者:未知
...
查看刚刚下载的安装可执行文件的属性时,它会显示签名,并告诉我签名有效。
此外,整个证书链都是有效的。
我用这样的东西签名:
SignTool.exe sign /v /t http://timestamp.verisign.com/scripts/timstamp.dll
/f "my-authenticode.pfx" /p "my-password" "my-setup.exe"
Run Code Online (Sandbox Code Playgroud)
(为了可读性添加了换行符)
我的问题:
有没有人知道可能的原因(和修复)?
更多信息:
我能想到可能的原因:
更新 1:
我发现了 2013 年的 MSDN 博客文章,它似乎谈论了我发现的类似内容,但我仍然看不出这是否真的适用。
更奇怪的是:从我们网站上下载的旧版本,使用相同的 Authenticode 证书签名不会触发警告。
也许 SmartScreen 会比较时间戳并对较新的签名/安装可执行文件有不同的行为?
也许我需要在调用 SignTool.exe 时添加其他/不同的参数? …
我多年来一直使用 SHA1 签名,但从 2016 年开始,Windows 强制开发人员使用 SHA256。
Windows 对 Authenticode 代码签名和时间戳的强制执行
通过使用 Windows 7 SDK signtool,对 SHA-256 进行签名的函数是“未知命令”,因此此 signtool 作为 signtool 已过时,不应再使用。
为了使用 SHA256 进行签名,我下载了 Windows 8.1 SDK 以获取具有新功能(/fd 和其他一些功能)的 signtool.exe。BAT 文件和 signtool 适用于 Windows 8 和 10,所以我知道它可以工作,但在 Windows 7 上尝试为文件添加时间戳时会崩溃。
我使用 bat 文件对文件进行签名,如下所示(我编辑了 BAT 文件,因此它不显示变量、完整路径、公司名称和密码):
Path\signtool.exe sign /f "Path\Certificate.p12" /fd sha256 /p *password* /du "URL" /tr "timestampServer?td=sha256" /td sha256 /d "Product name" "Filename"
Run Code Online (Sandbox Code Playgroud)
我想,我没有合适的 SDK 来支持某些功能,但我在互联网上找不到任何关于如何在 Windows 7 上设置它的信息。我尝试安装 MS Visual C++ 2015 Redistributable (x64 ) 在我的机器上没有解决问题。
我有一个具有以下结构的 .Net 解决方案:
我希望仅对我自己的二进制文件(a.exe 和 b.dll)进行 Authenticode 签名。
我目前在 a.exe 的 csproj 文件上有一个生成后事件:
"C:\Program Files (x86)\Windows Kits\10\bin\x86\signtool.exe" sign /t http://timestamp.globalsign.com/scripts/timestamp.dll /a $(TargetPath)
for %%f in ("$(ProjectDir)$(OutDir)*.dll") do "C:\Program Files (x86)\Windows Kits\10\bin\x86\signtool.exe" sign /t http://timestamp.globalsign.com/scripts/timestamp.dll /a $(TargetPath) %%f
Run Code Online (Sandbox Code Playgroud)
但是,这将对包括thirdParty.dll 在内的所有dll 进行签名,并且还存在尝试对任何非托管DLL 进行签名的风险。
现在,最简单的解决方案是在 b.dll 的 csproj 文件上放置一个构建后事件,并删除上面所示的 for 循环。然而,实际上我们有许多组件,并且可能会添加更多组件。我不想依赖其他开发人员记得添加构建后步骤来对任何新程序集进行 Authenticode 签名。
我可以使用此处描述的 PowerShell 脚本仅对托管程序集进行签名,但这仍会在上面的示例中对thirdParty.dll 进行签名。
如何仅枚举并签署包含我自己的代码的程序集?
我想对单文件发布的 .net core 应用程序中的二进制文件进行签名。这是因为我希望这些库在解压到 时进行数字签名。这是我的项目文件的缩短版本。%temp%\.net\%app_name%\%random_dir%
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<PublishTrimmed>false</PublishTrimmed>
<PublishReadyToRun>false</PublishReadyToRun>
<Configuration>Release</Configuration>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
</PropertyGroup>
<Target Name="SignPrePublishedFiles" AfterTargets="ComputeAndCopyFilesToPublishDirectory">
<ItemGroup>
<FileToSign Include="$(OutDir)Foo.*.dll" />
</ItemGroup>
<Exec Command="jsign ~~~params removed for brevity~~~ %(FileToSign.Identity)" />
</Target>
</Project>
Run Code Online (Sandbox Code Playgroud)
目标在目录SignPrePublishedFiles
中签署所需的文件$(OutDir)
,但发布的应用程序包含未签名的二进制文件。我认为这是因为以下时间不正确:AfterTargets="ComputeAndCopyFilesToPublishDirectory"
或文件夹不正确,我假设$(OutDir)
用于发布。在这里,我使用jsign因为构建在 Linux 上运行,但签名是针对 Windows 二进制文件完成的。
如何签署已发布的文件,特别是单文件应用程序内的文件?
authenticode ×10
.net ×5
code-signing ×4
c# ×3
msbuild ×3
signtool ×2
windows ×2
.net-core ×1
asn.1 ×1
c ×1
c++-cli ×1
open-source ×1
publishing ×1
sha ×1
sha256 ×1
strongname ×1
windows-10 ×1
x509 ×1