如何检查文件是否有数字签名

问题描述 投票:0回答:7

我想以编程方式检查文件是否经过数字签名。

目前,我发现了一个相当晦涩的Microsoft代码,它无法编译......

对这个主题有什么想法吗?

顺便说一句,带有命令行的外部工具也很棒。

certificate code-signing
7个回答
40
投票

答案中提到

signtool
的重要缺失部分,例如对于具有签名的 DevOps/部署构建,请参见此处:

是的,通过众所周知的

signtool.exe
,您还可以了解文件是否已签名。无需下载其他工具!

例如用简单的线条:

signtool verify /pa myfile.exe
if %ERRORLEVEL% GEQ 1 echo This file is not signed.

(对于详细输出,请在

/v
之后添加
/pa
。)

有人可能会问:为什么这很重要?我只需(再次)签署应签署的文件即可工作。

我的目标是保持构建干净,并且不要再次签署文件,因为不仅日期发生了变化,而且之后的二进制文件也不同了。 不适合比较任务。 业务示例: 我的客户有一个简化的自动化“开发操作”类型的构建和构建后流程。不同的文件集有多个来源,最后所有内容都经过构建、测试并捆绑到分发中,为此某些文件必须进行签名。为了保证某些文件不会在未经签名的情况下离开设备,我们过去常常对媒体上找到的所有重要文件进行签名,即使它们已经签名。

但这还不够干净!一般来说:

  1. 如果我们再次对已经签名的文件进行签名,则文件日期和二进制指纹会发生变化,并且文件将失去与其源的可比性(如果只是复制)。 (至少如果您使用时间戳进行签名,我们总是这样做,并且我认为强烈建议这样做。)

这是严重的质量损失,因为尽管文件本身没有更改,但该文件不再与其前身相同。

  1. 如果我们再次签署文件,当它是不应由我们公司签署的第三方文件时,这也可能是一个错误。

您可以通过根据前面提到的

signtool verify
调用的返回代码使签名本身有条件来避免这两种情况。

附注2024:显然,这仅适用于本身包含签名的文件,我认为您自己的文件也应该如此。


34
投票

下载

Sigcheck
并使用以下命令。

sigcheck.exe -a -u -e 

签名 dll 的示例

File version:   0.0.0.0
Strong Name:    Signed

未签名 dll 的示例

File version:   0.0.0.0
Strong Name:    Unsigned

Sigcheck
是一个显示文件版本号的命令行实用程序。祝你好运


26
投票

自 PowerShell 5.1 起,您可以使用

Get-AuthenticodeSignature
验证二进制文件或 PowerShell 脚本的签名。

> Get-AuthenticodeSignature -FilePath .\MyFile.exe

SignerCertificate                 Status        Path                                                                                   
-----------------                 ------        ----                                                                                   
A59E92E31475F813DDAF41C3CCBC8B78  Valid         MyFile.exe   

或者

> (Get-AuthenticodeSignature -FilePath .\MyFile.exe).Status
Valid

17
投票

我在网络上找到了另一个选项(纯.NET代码)这里

代码非常简单并且有效。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

internal class Program
{
    private static void Main(string[] args)
    {
        string filePath = args[0];

        if (!File.Exists(filePath))
        {
            Console.WriteLine("File not found");
            return;
        }

        X509Certificate2 theCertificate;

        try
        {
            X509Certificate theSigner = X509Certificate.CreateFromSignedFile(filePath);
            theCertificate = new X509Certificate2(theSigner);
        }
        catch (Exception ex)
        {
            Console.WriteLine("No digital signature found: " + ex.Message);

            return;
        }

        bool chainIsValid = false;

        /*
         *
         * This section will check that the certificate is from a trusted authority IE
         * not self-signed.
         *
         */

        var theCertificateChain = new X509Chain();

        theCertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;

        /*
         *
         * Using .Online here means that the validation WILL CALL OUT TO THE INTERNET
         * to check the revocation status of the certificate. Change to .Offline if you
         * don't want that to happen.
         */

        theCertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;

        theCertificateChain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);

        theCertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;

        chainIsValid = theCertificateChain.Build(theCertificate);

        if (chainIsValid)
        {
            Console.WriteLine("Publisher Information : " + theCertificate.SubjectName.Name);
            Console.WriteLine("Valid From: " + theCertificate.GetEffectiveDateString());
            Console.WriteLine("Valid To: " + theCertificate.GetExpirationDateString());
            Console.WriteLine("Issued By: " + theCertificate.Issuer);
        }
        else
        {
            Console.WriteLine("Chain Not Valid (certificate is self-signed)");
        }
    }
}

14
投票

如果需要外部工具,可以使用signtool.exe。它是 Windows SDK 的一部分,它需要命令行参数,您可以在此处了解更多信息,http://msdn.microsoft.com/en-us/library/aa387764.aspx


3
投票

您也可以尝试使用 npm 包

sign-check
来实现此目的。

此包实现了 WinVerifyTrust API,并且使用简单:

npm install -g sign-check

sign-check 'path/to/file'

0
投票

选择

<*>.exe
右键单击 > 属性。如果文件已签名,那么您将在该文件的属性窗口中看到此选项卡。

© www.soinside.com 2019 - 2024. All rights reserved.