38

我想以编程方式检查文件是否已进行数字签名。

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

对这个主题有任何想法吗?

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

4

7 回答 7

31

答案提到的重要缺失部分signtool是:

是的,您还可以通过众所周知的signtool.exe方式找出文件是否已签名。无需下载其他工具!

例如用简单的线:

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

(对于详细输出,请在/v之后添加/pa。)

有人可能会问:为什么这很重要?我只是(再次)签署应该签署的文件并且它可以工作。

我的目标是保持构建干净,并且不要第二次签署文件,因为不仅日期改变了,而且之后的二进制文件也不同。

业务示例:我的客户有一个简化的自动化“开发操作”类构建和构建后流程。不同的文件集有多个来源,最后所有文件都经过构建、测试和捆绑分发 - 为此必须对一些文件进行签名。为保证某些文件在没有签名的情况下不会离开设备,我们曾经对媒体上找到的所有重要文件进行签名,即使它们已经签名。

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

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

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

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

您可以通过根据前面提到的调用的返回码使签名本身有条件来避免这两种情况signtool verify

于 2014-03-17T23:24:24.360 回答
30

下载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是一个显示文件版本号的命令行实用程序。祝你好运

于 2013-06-17T23:09:16.310 回答
14

我在网上找到了另一个选项(纯 .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)");
        }
    }
}
于 2015-12-10T11:39:37.993 回答
13

如果需要外部工具,可以使用 signtool.exe。它是 Windows SDK 的一部分,它接受命令行参数,你可以在这里找到更多关于它的信息, http: //msdn.microsoft.com/en-us/library/aa387764.aspx

于 2009-03-20T17:14:47.993 回答
8

从 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
于 2020-08-04T08:23:18.097 回答
3

您也可以尝试为此sign-check目的使用 npm 包。

这个包实现了 WinVerifyTrust API 并且使用简单:

npm install -g sign-check

sign-check 'path/to/file'
于 2017-08-19T12:00:38.017 回答
0

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

文件的属性

于 2017-03-07T10:27:18.320 回答