2014-06-05 8 views
11

Meine .NET-Exe ist mit Signtool signiert. diesen Code verwenden, kann ich die Gültigkeit des Zertifikats selbst überprüfen:Überprüfen der digitalen Signatur auf EXE

var cert = X509Certificate.CreateFromSignedFile("application.exe"); 
var cert2 = new X509Certificate2(cert.Handle); 
bool valid = cert2.Verify(); 

aber nur, prüft das Zertifikat selbst und nicht die Unterschrift der EXE-Datei. Wenn die EXE manipuliert wird, erkennt diese Methode daher nicht.

Wie kann ich die Signatur überprüfen?

[DllImport("mscoree.dll", CharSet = CharSet.Unicode)] 
public static extern bool StrongNameSignatureVerificationEx(
     string wszFilePath, bool fForceVerification, ref bool pfWasVerified);  

var assembly = Assembly.GetExecutingAssembly(); 
bool pfWasVerified = false; 
if (!StrongNameSignatureVerificationEx(assembly.Location, true, ref pfWasVerified)) 
{   
    // it's a patched .exe file! 
} 

Aber es ist nicht genug:

+0

'X509Certificate.CreateFromSignedFile (" "). Verify()'? – Sinatr

+0

.CreateFromSignedFile gibt eine Instanz von X509Certificate zurück und hat keine .Verify-Methode. – LTR

+0

Ok, dann noch eine dumme Idee: Konstruiere 'X509Certificate2' mit' X509Certificate', nicht 'Handle'. Ich rate: 'Verify' Methode * sollte * überprüfen Sie die Datei auch oder Zertifikat wird Ausnahme auslösen (wenn Instanziierung?) Wenn exe-Datei manipuliert wird. Vielleicht müssen Sie eine eigene Validierung [Kette] implementieren (http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509chain.aspx). – Sinatr

Antwort

9

Sie müssen (P/Invoke) WinVerifyTrust() Funktion von,aufrufen. Es gibt (soweit ich weiß) keine Alternative in Managed .NET.

Sie finden eine Dokumentation dieser Methode here.

Jemand hat diese Frage bereits auf SO gestellt. Es wurde nicht akzeptiert, aber es sollte korrekt sein (ich scrollte nur durch). Take a look.

Sie könnten auch einen Blick auf this guide werfen, aber sie machen wirklich das gleiche.

+0

Danke! Ich dachte, wenn Sie die Signatur von der EXE laden und die Kette mit der X590Certificate-Klasse überprüfen können, muss es eine Möglichkeit geben, die Integrität der Datei zu überprüfen. Werde dann mit P/Invoke gehen. – LTR

1

Um die Integrität der signierten Exe-Datei zu validieren, können wir StrongNameSignatureVerificationEx Methode verwenden. Es ist möglich, die Signatur zu entfernen und sie dann erneut anzuwenden/neu zu erstellen! (Es gibt viele Tools, um das zu tun) In diesem Fall müssen Sie den öffentlichen Schlüssel Ihrer Signatur irgendwo (als Ressource) speichern und dann mit dem neuen/gegenwärtigen öffentlichen Schlüssel vergleichen. more info here

+6

Authenticode Signatur von Signtool und starke Benennung sind zwei verschiedene Dinge. –

1

Ich suchte Github und fand Azure Microsoft C# code, die das PowerShell-Objekt verwendet, um nach einer gültigen Authenticode-Signatur zu suchen.

/// <summary> 
    /// Check for Authenticode Signature 
    /// </summary> 
    /// <param name="providedFilePath"></param> 
    /// <returns></returns> 
    private bool VerifyAuthenticodeSignature(string providedFilePath) 
    { 
     bool isSigned = true; 
     string fileName = Path.GetFileName(providedFilePath); 
     string calculatedFullPath = Path.GetFullPath(providedFilePath); 

     if (File.Exists(calculatedFullPath)) 
     { 
      Log.LogMessage(string.Format("Verifying file '{0}'", calculatedFullPath)); 
      using (PowerShell ps = PowerShell.Create()) 
      { 
       ps.AddCommand("Get-AuthenticodeSignature", true); 
       ps.AddParameter("FilePath", calculatedFullPath); 
       var cmdLetResults = ps.Invoke(); 

       foreach (PSObject result in cmdLetResults) 
       { 
        Signature s = (Signature)result.BaseObject; 
        isSigned = s.Status.Equals(SignatureStatus.Valid); 
        if (isSigned == false) 
        { 
         ErrorList.Add(string.Format("!!!AuthenticodeSignature status is '{0}' for file '{1}' !!!", s.Status.ToString(), calculatedFullPath)); 
        } 
        else 
        { 
         Log.LogMessage(string.Format("!!!AuthenticodeSignature status is '{0}' for file '{1}' !!!", s.Status.ToString(), calculatedFullPath)); 
        } 
        break; 
       } 
      } 
     } 
     else 
     { 
      ErrorList.Add(string.Format("File '{0}' does not exist. Unable to verify AuthenticodeSignature", calculatedFullPath)); 
      isSigned = false; 
     } 

     return isSigned; 
    }