Reputation:
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
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:
This is a severe quality loss, because this file is no longer identical to it's predecessors although the file itself has not changed.
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
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
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
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
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
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.
Upvotes: 0
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