2010-12-03 34 views
6

私のアプリケーションでは、署名されているかどうかを確認する必要があります。署名されている場合は実行を継続し、そうでない場合はアプリケーションを終了します。 signtoolを使用してアプリケーションに署名します。 これを行うためのC#コードはありますか?ここで実行ファイルが署名されているかどうかを確認する(signtoolがそのexeに署名するために使用される)

+2

あなたはアプリに署名するために何を使用していますか? – Lazarus

+0

実際、私はsigntoolを使用しています。 –

答えて

5

はそれをしないのユーティリティメソッドです:

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

それは解決策として非常に複雑です、私はちょうど真偽が必要です:exeは署名され、exeは署名されていません –

+0

私はあなたが多くの選択肢があるとは思わない。 Authenticodeチェックはそれほど簡単ではありません。コードをコピーして最後の関数を呼び出してください:internal static uint WinVerifyTrust(string fileName)。返された0は署名されていることを意味します。 –

+0

@AnasehがSimonの指摘しているように、署名の検証は単なる真偽以外にもあります。署名の有無、有効性、署名を作成するために使用された証明書の有効性、タイムスタンプの有効性、タイムスタンプの署名に使用される証明書を決定する必要があります。 –

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

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

私にそれを打つ、私はAssemblyName.GetPublicKey()を提案しようとしていたhttp://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.getpublickey%28VS.80% 29.aspx – pstrjds

+0

ありがとうございますが、アセンブリ署名を使用していないため、このソリューションは機能しません。アプリケーションに署名するためにsigntoolを使用しています。 –

+1

はい、signtoolはAuthenticode署名を作成します。強い名前の鍵の署名。下の私の答えを見てください。 –

0

私はあなたが 'CryptUIWizDigitalSign' APIを使用することをお勧め。 This linkを参照として使用できます。

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 
関連する問題