Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determining if a file has a digital signature in c# without actually verifying the signature

Is there a simple way to check if a digital signature exists on a file without trying to verify the certificate it was signed with?

I want to sign a long list of exe & dll files in a directory, but only files that haven't yet been signed.

For example, if one of the files has been signed by Microsoft or some other 3rd party I don't want to sign them again with my company's certificate.

It is easy to check if a file has a digital signature or not by right-clicking the file and viewing its properties (if the digital signature tab shows up then it has been signed). I'm searching for a simple way to check for this digital signature property using C#.

Right now, I am using the verify command with signtool.exe - which doesn't only check to see if a digital signature exists, but also whether the certificate used to sign the file was issued by a trusted authority.

Here is my simple, yet clunky approach for doing this:

private static Boolean AlreadySigned(string file)
{
    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.RedirectStandardOutput = true;
    startInfo.RedirectStandardError = true;
    startInfo.FileName = "signTool.exe";
    startInfo.Arguments = "verify /v " + file;
    startInfo.UseShellExecute = false;

    Process process = new Process();
    process.StartInfo = startInfo;
    process.EnableRaisingEvents = true;
    process.Start();
    process.WaitForExit();
    string output = process.StandardOutput.ReadToEnd();

    return output.Contains("Signing Certificate Chain:");
}

Notice that I'm using the verbose flag "/v" and checking if the output contains the text "Signing Certificate chain:" - just because I noticed that that string was always in the output of a file that had been signed - and was omitted from any file that hadn't been signed.

Anyway, despite its clumsiness, this code seems to get the job done. One reason I'd like to change it though is because it appears to take a few hundred milliseconds to execute the verify command on a file. I don't need to verify the certificate I'm just trying to see if a digital signature exists on the file.

So in short, is there a simple way to check if a digital signature exists - without trying to verify it?

like image 693
ksun Avatar asked Apr 11 '13 00:04

ksun


People also ask

How do I find the signature of a downloaded file?

The digital signature of a Windows executable file (a file with an .exe extension) can be verified after the file has been downloaded and saved: In your Downloads folder (in Windows Explorer), right-click the downloaded .exe file and click Properties. Click the Digital Signatures tab.

How do you check if a DLL is digitally signed?

From a Windows operating system: Right click the file the main executable file (.exe), select Properties > Digital Signatures. Under Signature list, select the Signature, and click Details. You will see information regarding the Code Signing certificate that was used to sign the executable.

How do I find an electronic signature?

Methods to check the signature of an electronic documentOTP SMS access code: signers must enter a one-time passcode sent via SMS text message. Video-based onboarding validation: signers are requested to prove their identity through a video selfie and a picture of their ID document.


1 Answers

I came up with a pretty decent solution using the "Get-AuthenticodeSignature" powershell command. I found this site that explains how to use powershell commands in c#. This way I don't need to spawn several processes, and it's pretty quick.

using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;


private static Boolean alreadySigned(string file)
{            
            try
            {
                RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
                Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
                runspace.Open();

                Pipeline pipeline = runspace.CreatePipeline();
                pipeline.Commands.AddScript("Get-AuthenticodeSignature \"" + file + "\"");

                Collection<PSObject> results = pipeline.Invoke();
                runspace.Close();
                Signature signature = results[0].BaseObject as Signature;
                return signature == null ? false : (signature.Status != SignatureStatus.NotSigned);
            }
            catch (Exception e)
            {
                throw new Exception("Error when trying to check if file is signed:" + file + " --> " + e.Message);
            }
}
like image 179
ksun Avatar answered Oct 20 '22 12:10

ksun