Vinzz
Vinzz

Reputation:

How to check if a file has a digital signature

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.

Upvotes: 60

Views: 147328

Answers (7)

Philm
Philm

Reputation: 3674

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.

Upvotes: 44

Kantium
Kantium

Reputation: 652

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

Upvotes: 33

OSH
OSH

Reputation: 2937

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)");
        }
    }
}

Upvotes: 18

RckLN
RckLN

Reputation: 4484

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

Upvotes: 36

kami4ka
kami4ka

Reputation: 193

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'

Upvotes: 3

run
run

Reputation: 1186

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

Upvotes: 0

LanceSc
LanceSc

Reputation: 2124

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

Upvotes: 14

Related Questions