2010-12-03 32 views

Répondre

5

Voici une méthode utilitaire qui le fait:

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); 
+1

C'est très compliqué comme solution, j'ai juste besoin d'un vrai ou faux: exe signé, exe non signé –

+0

Je ne pense pas que vous ayez beaucoup de choix. Le contrôle Authenticode n'est pas si simple. Copiez simplement le code et appelez la dernière fonction: intint static static WinVerifyTrust (string fileName). Un 0 renvoyé signifie qu'il est signé. –

+0

@Anaseh comme Simon a souligné, la validation de la signature est plus que juste vrai ou faux. Vous devez déterminer la présence de la signature, sa validité, puis la validité du certificat utilisé pour faire une signature, la validité de l'horodatage et le certificat utilisé pour signer un horodatage. –

1
private bool IsAssemblySigned() 
    { 
     var assembly = Assembly.GetAssembly(GetType()); 

     var assemblyName = assembly.GetName(); 
     var key = assemblyName.GetPublicKey(); 
     return key.Length > 0; 
    } 
+0

Battez-moi, j'allais suggérer AssemblyName.GetPublicKey() http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.getpublickey%28VS.80% 29.aspx – pstrjds

+0

Merci pour votre réponse, mais cette solution ne fonctionnera pas parce que je n'utilise pas la signature de l'Assemblée, j'utilise signtool pour signer l'application –

+1

oui, signtool crée la signature Authenticode, à ne pas confondre avec .NET signature de clé de nom fort. Voir ma réponse ci-dessous. –

0

Je vous suggère d'utiliser l'API "CryptUIWizDigitalSign. This link peut être utilisé comme référence.

0
Try 
     Dim objCertificate As New Security.Cryptography.X509Certificates.X509Certificate2(Security.Cryptography.X509Certificates.X509Certificate.CreateFromSignedFile(strFile)) 
     Return True 

    Catch ex As Exception 
     Return False 
    End Try