Проверьте, подписан ли исполняемый файл или нет (signtool используется для подписи этого исполняемого файла)

В моем приложении мне нужно проверить, подписано оно или нет. Если он подписан, продолжайте выполнение и выйдите из приложения, если нет. Signtool будет использоваться для подписи приложения. Есть ли какой-нибудь код С# для этого?


person Anas EL HAJJAJI    schedule 03.12.2010    source источник
comment
Что вы используете для подписи приложения?   -  person Lazarus    schedule 03.12.2010
comment
На самом деле, я использую signtool.   -  person Anas EL HAJJAJI    schedule 03.12.2010


Ответы (3)


Вот служебный метод, который делает это:

var signed = IsSigned(@"c:\windows\explorer.exe");
...
public static bool IsSigned(string filePath)
{
    if (filePath == null)
        throw new ArgumentNullException(nameof(filePath));

    var file = new WINTRUST_FILE_INFO();
    file.cbStruct = Marshal.SizeOf(typeof(WINTRUST_FILE_INFO));
    file.pcwszFilePath = filePath;

    var data = new WINTRUST_DATA();
    data.cbStruct = Marshal.SizeOf(typeof(WINTRUST_DATA));
    data.dwUIChoice = WTD_UI_NONE;
    data.dwUnionChoice = WTD_CHOICE_FILE;
    data.fdwRevocationChecks = WTD_REVOKE_NONE;
    data.pFile = Marshal.AllocHGlobal(file.cbStruct);
    Marshal.StructureToPtr(file, data.pFile, false);

    int hr;
    try
    {
        hr = WinVerifyTrust(INVALID_HANDLE_VALUE, WINTRUST_ACTION_GENERIC_VERIFY_V2, ref data);
    }
    finally
    {
        Marshal.FreeHGlobal(data.pFile);
    }
    return hr == 0;
}

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct WINTRUST_FILE_INFO
{
    public int cbStruct;
    public string pcwszFilePath;
    public IntPtr hFile;
    public IntPtr pgKnownSubject;
}

[StructLayoutAttribute(LayoutKind.Sequential)]
private struct WINTRUST_DATA
{
    public int cbStruct;
    public IntPtr pPolicyCallbackData;
    public IntPtr pSIPClientData;
    public int dwUIChoice;
    public int fdwRevocationChecks;
    public int dwUnionChoice;
    public IntPtr pFile;
    public int dwStateAction;
    public IntPtr hWVTStateData;
    public IntPtr pwszURLReference;
    public int dwProvFlags;
    public int dwUIContext;
    public IntPtr pSignatureSettings;
}

private const int WTD_UI_NONE = 2;
private const int WTD_REVOKE_NONE = 0;
private const int WTD_CHOICE_FILE = 1;
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private static readonly Guid WINTRUST_ACTION_GENERIC_VERIFY_V2 = new Guid("{00AAC56B-CD44-11d0-8CC2-00C04FC295EE}");

[DllImport("wintrust.dll")]
private static extern int WinVerifyTrust(IntPtr hwnd, [MarshalAs(UnmanagedType.LPStruct)] Guid pgActionID, ref WINTRUST_DATA pWVTData);
person Simon Mourier    schedule 03.12.2010
comment
Это очень сложное решение, мне нужно только true или false: exe подписано, exe не подписано - person Anas EL HAJJAJI; 03.12.2010
comment
Я не думаю, что у вас есть большой выбор. Проверка подлинности не так проста. Просто скопируйте код и вызовите последнюю функцию: внутренний статический uint WinVerifyTrust(string fileName). Возвращенный 0 означает, что он подписан. - person Simon Mourier; 03.12.2010
comment
@ Анасех, как указал Саймон, проверка подписи - это больше, чем просто правда или ложь. Вам необходимо определить наличие подписи, ее действительность, затем действительность сертификата, использованного для создания подписи, действительность метки времени и сертификата, используемого для подписи метки времени. - person Eugene Mayevski 'Callback; 03.12.2010

Я бы посоветовал вам использовать API CryptUIWizDigitalSign. Эта ссылка может использоваться как справочная.

person Prasanna K Rao    schedule 03.12.2010

person    schedule
comment
Опередите меня, я собирался предложить AssemblyName.GetPublicKey() msdn.microsoft.com/en-us/library/ - person pstrjds; 03.12.2010
comment
Спасибо за ваш ответ, но это решение не будет работать, потому что я не использую подпись сборки, я использую инструмент подписи для подписи приложения - person Anas EL HAJJAJI; 03.12.2010
comment
да, signtool создает подпись Authenticode, не путать с подписью ключа строгого имени .NET. Смотрите мой ответ ниже. - person Simon Mourier; 03.12.2010