确定文件是否在c#中具有数字签名而不实际验证签名

ksu*_*sun 11 c# signing digital-signature file-properties

有没有一种简单的方法来检查文件上是否存在数字签名而不尝试验证其签名的证书?

我想在目录中签署一长串exe和dll文件,但只包含尚未签名的文件.

例如,如果其中一个文件已由Microsoft或其他第三方签名,我不想再使用我公司的证书签名.

通过右键单击文件并查看其属性(如果数字签名选项卡显示已签名),可以轻松检查文件是否具有数字签名.我正在寻找一种使用C#检查此数字签名属性的简单方法.

现在,我正在使用带有signtool.exe的verify命令 - 它不仅检查数字签名是否存在,还检查用于签署文件的证书是否由受信任的机构颁发.

这是我执行此操作的简单而笨重的方法:

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:");
}
Run Code Online (Sandbox Code Playgroud)

请注意,我正在使用详细标记"/ v"并检查输出是否包含文本"签名证书链:" - 只是因为我注意到该字符串始终位于已签名的文件的输出中 - 并且从任何尚未签名的文件中省略.

无论如何,尽管它的笨拙,这段代码似乎完成了工作.我想改变它的一个原因是因为它似乎需要几百毫秒才能对文件执行verify命令.我不需要验证证书我只是想看看文件上是否存在数字签名.

简而言之,是否有一种简单的方法来检查数字签名是否存在 - 而不是试图验证它?

ksu*_*sun 9

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);
            }
}
Run Code Online (Sandbox Code Playgroud)


Mik*_*ray 6

如果要对.NET程序集执行此操作,可以执行以下操作:

        string filePath = "C:/path/to/file.dll";
        Assembly assembly = Assembly.LoadFrom(filePath);
        Module module = assembly.GetModules().First();
        X509Certificate certificate = module.GetSignerCertificate();
        if (certificate == null)
        {
             // file is not signed.
        }
Run Code Online (Sandbox Code Playgroud)

X509Certificate类有一些静态方法,也可以使用(例如CreateFromSignedFile),但我不熟悉他们.这是我们用来仔细检查我们的内部工具是否已应用数字签名的方法.