Как проверить, подписан ли файл на С#?

Я пишу программу, которой нужно загрузить несколько других файлов. есть ли способ проверить, подписаны ли эти файлы или нет, не щелкая их правой кнопкой мыши и не проверяя? Я использую 300-400 файлов, которые меняются каждые несколько дней, мне нужно проверить DLL/EXE/CAB/OCX/MSI (и, возможно, также vbs/js)

есть ли способ проверить это?


person Ben2307    schedule 06.07.2011    source источник
comment
Если у вас нет конкретной проблемы с этим, помощи может быть недостаточно, за исключением некоторых ссылок, которые вы потенциально могли найти лично - пожалуйста, сообщите нам, что вы пытались до сих пор.   -  person Grant Thomas    schedule 06.07.2011
comment
@Tigran: Подписание кода. msdn.microsoft.com/en-us/library /ms537361(v=vs.85).aspx   -  person    schedule 06.07.2011
comment
возможный дубликат , как проверить, есть ли у файла цифровая подпись   -  person    schedule 06.07.2011
comment
Хорошо, цифровая подпись, спасибо...   -  person Tigran    schedule 06.07.2011
comment
Я не согласен с тем, что этот вопрос не является реальным вопросом или неконструктивным. Близкие должны прочитать, что он просит.. это подпись кода. Щелчок правой кнопкой мыши и проверка свойств файла — это ручной способ проверить, подписан ли файл. Я согласен, что это дубликат, и я разместил ссылку.   -  person    schedule 06.07.2011
comment
Проверьте этот пост, я думаю, это то, что вы ищете: stackoverflow.com/questions/667017/   -  person Tigran    schedule 06.07.2011
comment
@Мистер. Разочарование: он запрашивает подпись кода/цифровые сертификаты и как проверить, подписан ли файл.   -  person    schedule 06.07.2011
comment
@ 0A0D Моя точка зрения остается в силе (только теперь подчеркнута, учитывая предоставленный ответ).   -  person Grant Thomas    schedule 06.07.2011
comment
@Мистер. Разочарование: он явно не знает, как это сделать, иначе бы не спрашивал.   -  person    schedule 06.07.2011
comment
Хм, если это не про цифровую подпись, то о чем этот вопрос?   -  person Tigran    schedule 06.07.2011
comment
речь идет о цифровой подписи. означает ли 'Assembly.LoadFile().IsFullyTrusted()', что он подписан?   -  person Ben2307    schedule 07.07.2011
comment
Этот вопрос был закрыт без уважительной причины, но я разместил соответствующее решение здесь: stackoverflow.com/a/34200959/1037208   -  person OSH    schedule 10.12.2015
comment
См. этот crookm.com/journal/2019. /verify-signed-executables-in-dotnet/   -  person Ahmed Osama    schedule 23.05.2020


Ответы (1)


Предполагая, что вы хотите проверить, подписан ли файл Authenticode и что сертификат доверен, вы можете подключиться к WinVerifyTrust в Wintrust.dll.

Ниже приведена оболочка (более или менее воспроизведенная отсюда), которая можно назвать следующим образом:

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;

    }

}
person spender    schedule 06.07.2011
comment
Также см. pinvoke.net/default.aspx/wintrust.winverifytrust для других взаимодействий. примечания о функции WinVerifyTrust. - person tomasdeml; 22.01.2016