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

发布于 2024-07-15 13:57:16 字数 267 浏览 6 评论 0原文

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

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

对此主题有什么想法吗?

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

I'd like to check programatically if a file has been digitally signed or not.

For the moment, I found a rather obscure Microsoft code, that doesn't compile...

Any idea on the subject?

An external tool with command line would also be great, by the way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

初熏 2024-07-22 13:57:16

答案中提到 signtool 的重要缺失部分,例如,对于带有签名的 DevOps/部署构建,在这里:

是的,使用众所周知的 signtool.exe 您还可以找到,如果文件已签名。 无需下载其他工具!

例如,使用简单的一行:(

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

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

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

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

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

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

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

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

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

PS 2024:显然,这仅适用于本身包含签名的文件,我认为您自己的文件也应该是这种情况。

The important missing part of the answer mentioning signtool, e.g. for DevOps/deployment builds with signing is here:

Yes, with the well known signtool.exe you can also find out, if a file is signed. No need to download another tool!

E.g. with the simple line:

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

(For verbose output, add a /v after /pa.)

One may ask: Why this is important? I just sign the files (again) which shall be signed and it works.

My objective is to keep builds clean, and don't sign files a second time because not only the date is changed, but the binary is different after that.
Bad for compare tasks.
Business example:
My client has a streamlined automated "dev ops" kind build and post build process. There are multiple sources for different file sets, and at the end all is build, tested and bundled to distribution- and for that some files have to be signed. To guarantee that some files don't leave the unit without being signed, we used to sign all important files found on the media, even if they were already signed.

But this hasn´t been clean enough ! Generally:

  1. If we sign a file again, which is already signed, the file date and binary fingerprint changes, and the file looses comparability with it's sources, if it was simply copied.
    (At least if you sign with a timestamp, which we always do and I think is highly recommended.)

This is a severe quality loss, because this file is no longer identical to it's predecessors although the file itself has not changed.

  1. If we sign a file again, this also could be a fault when it is a third party file which shouldn't be signed by our company.

You can avoid both by making the signing itself conditional depending on the return code of the preceding signtool verify call mentioned.

P.S. 2024: Obviously that this works only for files which contain their signature themselves which should be the case for your own files I assume.

漫漫岁月 2024-07-22 13:57:16

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

Download Sigcheck and use the following command.

sigcheck.exe -a -u -e 

An example of a signed dll

File version:   0.0.0.0
Strong Name:    Signed

An example of an unsigned dll

File version:   0.0.0.0
Strong Name:    Unsigned

Sigcheck is a command-line utility that shows file version number. Good Luck

白龙吟 2024-07-22 13:57:16

从 PowerShell 5.1 开始,您可以使用 获取-AuthenticodeSignature 用于验证二进制文件或 PowerShell 脚本的签名。

> Get-AuthenticodeSignature -FilePath .\MyFile.exe

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

或者

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

Since PowerShell 5.1, you can use Get-AuthenticodeSignature to verify the signature of a binary or a PowerShell script.

> Get-AuthenticodeSignature -FilePath .\MyFile.exe

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

Or

> (Get-AuthenticodeSignature -FilePath .\MyFile.exe).Status
Valid
我家小可爱 2024-07-22 13:57:16

我在网上找到了另一个选项(纯.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)");
        }
    }
}

I found another option (pure .NET code) on the web here.

The code is very simple and works.

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)");
        }
    }
}
香草可樂 2024-07-22 13:57:16

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

If you need an external tool, you can use signtool.exe. It is part of the Windows SDK, it takes command line arguments, and you can find out more about it here, http://msdn.microsoft.com/en-us/library/aa387764.aspx

乄_柒ぐ汐 2024-07-22 13:57:16

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

该包实现了 WinVerifyTrust API,并且用法简单:

npm install -g sign-check

sign-check 'path/to/file'

Also you can try to use npm package sign-check for that purposes.

This package implements WinVerifyTrust API and has simple usage:

npm install -g sign-check

sign-check 'path/to/file'
盗心人 2024-07-22 13:57:16

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

Select the <*>.exe rightclick >properties. if the file is signed then you will get this tab on the property windows of that file.

property of the file

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文