如何检查文件是不是在 C# 中签名? [关闭]
Posted
技术标签:
【中文标题】如何检查文件是不是在 C# 中签名? [关闭]【英文标题】:How to check if a file is signed in C#? [closed]如何检查文件是否在 C# 中签名? [关闭] 【发布时间】:2011-09-29 14:14:36 【问题描述】:我正在编写一个需要加载一些其他文件的程序。 有没有办法检查这些文件是否已签名,而无需右键单击它们并检查?我使用 300-400 个文件,每隔几天就会更改一次 我需要检查 DLL/EXE/CAB/OCX/MSI(也许还有 vbs/js)
有没有办法检查?
【问题讨论】:
除非您对此有特定的问题,否则除了您可能亲自找到的一些参考链接之外,帮助可能很少 - 请让我们知道您到目前为止所做的尝试。 @Tigran:代码签名。 msdn.microsoft.com/en-us/library/ms537361(v=vs.85).aspx how to check if a file has a digital signature的可能重复 我不同意这个问题不是一个真正的问题或没有建设性。关闭者应该阅读他的要求..这是代码签名。右键单击并检查文件的属性是查看文件是否已签名的手动方式。我同意它是重复的,并且我发布了链接。 这个问题无缘无故被关闭,但我在这里发布了一个相关的解决方案:***.com/a/34200959/1037208 【参考方案1】:假设您要检查文件是否经过 Authenticode 签名并且证书是受信任的,您可以在 Wintrust.dll
中 pinvoke 到 WinVerifyTrust
。
下面是一个包装器(或多或少转载from here),可以如下调用:
AuthenticodeTools.IsTrusted(@"path\to\some\signed\file.exe")
其中AuthenticodeTools
定义如下:
internal static class AuthenticodeTools
[DllImport("Wintrust.dll", PreserveSig = true, SetLastError = false)]
private static extern uint WinVerifyTrust(IntPtr hWnd, IntPtr pgActionID, IntPtr pWinTrustData);
private static uint WinVerifyTrust(string fileName)
Guid wintrust_action_generic_verify_v2 = new Guid("00AAC56B-CD44-11d0-8CC2-00C04FC295EE");
uint result=0;
using (WINTRUST_FILE_INFO fileInfo = new WINTRUST_FILE_INFO(fileName,
Guid.Empty))
using (UnmanagedPointer guidPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof (Guid))),
AllocMethod.HGlobal))
using (UnmanagedPointer wvtDataPtr = new UnmanagedPointer(Marshal.AllocHGlobal(Marshal.SizeOf(typeof (WINTRUST_DATA))),
AllocMethod.HGlobal))
WINTRUST_DATA data = new WINTRUST_DATA(fileInfo);
IntPtr pGuid = guidPtr;
IntPtr pData = wvtDataPtr;
Marshal.StructureToPtr(wintrust_action_generic_verify_v2,
pGuid,
true);
Marshal.StructureToPtr(data,
pData,
true);
result = WinVerifyTrust(IntPtr.Zero,
pGuid,
pData);
return result;
public static bool IsTrusted(string fileName)
return WinVerifyTrust(fileName) == 0;
internal struct WINTRUST_FILE_INFO : IDisposable
public WINTRUST_FILE_INFO(string fileName, Guid subject)
cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_FILE_INFO));
pcwszFilePath = fileName;
if (subject != Guid.Empty)
pgKnownSubject = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
Marshal.StructureToPtr(subject, pgKnownSubject, true);
else
pgKnownSubject = IntPtr.Zero;
hFile = IntPtr.Zero;
public uint cbStruct;
[MarshalAs(UnmanagedType.LPTStr)]
public string pcwszFilePath;
public IntPtr hFile;
public IntPtr pgKnownSubject;
#region IDisposable Members
public void Dispose()
Dispose(true);
private void Dispose(bool disposing)
if (pgKnownSubject != IntPtr.Zero)
Marshal.DestroyStructure(this.pgKnownSubject, typeof(Guid));
Marshal.FreeHGlobal(this.pgKnownSubject);
#endregion
enum AllocMethod
HGlobal,
CoTaskMem
;
enum UnionChoice
File = 1,
Catalog,
Blob,
Signer,
Cert
;
enum UiChoice
All = 1,
NoUI,
NoBad,
NoGood
;
enum RevocationCheckFlags
None = 0,
WholeChain
;
enum StateAction
Ignore = 0,
Verify,
Close,
AutoCache,
AutoCacheFlush
;
enum TrustProviderFlags
UseIE4Trust = 1,
NoIE4Chain = 2,
NoPolicyUsage = 4,
RevocationCheckNone = 16,
RevocationCheckEndCert = 32,
RevocationCheckChain = 64,
RecovationCheckChainExcludeRoot = 128,
Safer = 256,
HashOnly = 512,
UseDefaultOSVerCheck = 1024,
LifetimeSigning = 2048
;
enum UIContext
Execute = 0,
Install
;
[StructLayout(LayoutKind.Sequential)]
internal struct WINTRUST_DATA : IDisposable
public WINTRUST_DATA(WINTRUST_FILE_INFO fileInfo)
this.cbStruct = (uint)Marshal.SizeOf(typeof(WINTRUST_DATA));
pInfoStruct = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINTRUST_FILE_INFO)));
Marshal.StructureToPtr(fileInfo, pInfoStruct, false);
this.dwUnionChoice = UnionChoice.File;
pPolicyCallbackData = IntPtr.Zero;
pSIPCallbackData = IntPtr.Zero;
dwUIChoice = UiChoice.NoUI;
fdwRevocationChecks = RevocationCheckFlags.None;
dwStateAction = StateAction.Ignore;
hWVTStateData = IntPtr.Zero;
pwszURLReference = IntPtr.Zero;
dwProvFlags = TrustProviderFlags.Safer;
dwUIContext = UIContext.Execute;
public uint cbStruct;
public IntPtr pPolicyCallbackData;
public IntPtr pSIPCallbackData;
public UiChoice dwUIChoice;
public RevocationCheckFlags fdwRevocationChecks;
public UnionChoice dwUnionChoice;
public IntPtr pInfoStruct;
public StateAction dwStateAction;
public IntPtr hWVTStateData;
private IntPtr pwszURLReference;
public TrustProviderFlags dwProvFlags;
public UIContext dwUIContext;
#region IDisposable Members
public void Dispose()
Dispose(true);
private void Dispose(bool disposing)
if (dwUnionChoice == UnionChoice.File)
WINTRUST_FILE_INFO info = new WINTRUST_FILE_INFO();
Marshal.PtrToStructure(pInfoStruct, info);
info.Dispose();
Marshal.DestroyStructure(pInfoStruct, typeof(WINTRUST_FILE_INFO));
Marshal.FreeHGlobal(pInfoStruct);
#endregion
internal sealed class UnmanagedPointer : IDisposable
private IntPtr m_ptr;
private AllocMethod m_meth;
internal UnmanagedPointer(IntPtr ptr, AllocMethod method)
m_meth = method;
m_ptr = ptr;
~UnmanagedPointer()
Dispose(false);
#region IDisposable Members
private void Dispose(bool disposing)
if (m_ptr != IntPtr.Zero)
if (m_meth == AllocMethod.HGlobal)
Marshal.FreeHGlobal(m_ptr);
else if (m_meth == AllocMethod.CoTaskMem)
Marshal.FreeCoTaskMem(m_ptr);
m_ptr = IntPtr.Zero;
if (disposing)
GC.SuppressFinalize(this);
public void Dispose()
Dispose(true);
#endregion
public static implicit operator IntPtr(UnmanagedPointer ptr)
return ptr.m_ptr;
【讨论】:
有关WinVerifyTrust
函数的其他互操作说明,另请参见pinvoke.net/default.aspx/wintrust.winverifytrust。
FWIW 现在有一个优秀的纯 .NET 库github.com/vcsjones/AuthenticodeExaminer
@VivekRathod 很好的发现,但我对“纯 .NET 库”这个词持异议。 "The library is a wrapper around native Windows APIs that provide this functionality."
@spender 同意 - 正如你所指出的,我使用了这个词相当不正确。以上是关于如何检查文件是不是在 C# 中签名? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章