如何检查文件是不是在 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# 中签名? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何从 C# 应用程序检查与 ADCS 证书颁发机构服务器的连接? [关闭]

检查所有下载的文件c# [关闭]

检查列表是不是包含大于 C# 中的值的项目 [关闭]

使用 C# 检查 mdb 中的密码 [关闭]

如何检查字节数组是不是为有效的pdf文件[关闭]

C#做(不)调用事件[关闭]