English 中文(简体)
确定文件在 c# 中是否有数字签名, 而不实际验证签名
原标题: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?
最佳回答
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 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); } }
问题回答
If you want to do this for .NET assemblies, you can do this: 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. } The X509Certificate class has some static methods that may also be of use (e.g. CreateFromSignedFile), but I am not as familiar with them. This is method we use to double check that a digital signature has been applied by our internal tools.
Signtool works only with certain types of files (executables, scripts, and some rare formats) - it is not a tool for generic signature manipulation. For most file types signing can be done using either wrapping signature or embedded signature or detached signature. Wrapping a signature changes the actual file making it unreadable by those applications that are usually used to read it. Eg. if you create a wrapping signature on PDF, no PDF tool will be able to read the file until the signature is removed. Some file formats support embedded signatures right in their format (EXE files and the Authenticode format are the example). There you can embed the signature into the file and other applications are still able to read it. But this is format-specific and not many formats support this. Finally, detached signatures are kept separately from the file. I.e., if you have a file a.txt, you create a detached signature and put it into, for example, a.txt.pkcs7detached. As you see, the detached signatures are optimal for your task. And in this case, you have a list of .pkcs7detached files so you can check: if the file has no corresponding .pkcs7detached file with a signature, you create a new signature. All of the above signature types are supported by PKIBlackbox package of our SecureBlackbox product.




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签