2014-06-05 19 views
11

.NET exe của tôi được ký bằng signtool. Sử dụng mã này, tôi có thể xác minh tính hợp lệ của giấy chứng nhận bản thân:Kiểm tra chữ ký số trên EXE

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

Tuy nhiên, điều này chỉ kiểm tra giấy chứng nhận riêng của mình, và không phải là chữ ký của người EXE. Do đó, nếu EXE bị giả mạo, phương pháp này không phát hiện ra nó.

Tôi làm cách nào để kiểm tra chữ ký?

+0

'X509Certificate.CreateFromSignedFile (" "). Xác minh()'? – Sinatr

+0

.CreateFromSignedFile trả về phiên bản X509Certificate và không có phương thức .Verify. – LTR

+0

Ok, sau đó một ý tưởng ngu ngốc khác: xây dựng 'X509Certificate2' bằng cách sử dụng' X509Certificate', không phải là 'Xử lý'. Tôi đoán: 'Verify' phương pháp * nên * kiểm tra các tập tin cũng hoặc chứng chỉ sẽ ném ngoại lệ (khi instantiating?) Nếu có chứa exe-file là giả mạo. Có lẽ bạn phải thực hiện xác nhận riêng [chain] (http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509chain.aspx). – Sinatr

Trả lời

9

Bạn cần gọi (P/Invoke) WinVerifyTrust() chức năng từ wintrust.dll. Có (theo như tôi biết) không có thay thế trong quản lý .NET.

Bạn có thể tìm tài liệu về phương pháp này here.

Ai đó đã hỏi câu hỏi này trên SO. Nó không được chấp nhận, nhưng nó phải chính xác (tôi chỉ cuộn qua). Take a look.

Bạn cũng có thể xem this guide nhưng chúng thực sự giống nhau.

+0

Cảm ơn bạn! Tôi nghĩ nếu bạn có thể tải chữ ký từ EXE và xác minh chuỗi bằng cách sử dụng lớp X590Certificate, phải có một số cách để kiểm tra tính toàn vẹn của tệp. Sẽ đi với P/Invoke sau đó. – LTR

1

Để xác nhận tính toàn vẹn của tập tin .exe ký kết, chúng ta có thể sử dụng phương pháp StrongNameSignatureVerificationEx:

[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! 
} 

Nhưng nó không đủ. Có thể xóa chữ ký và sau đó áp dụng/tạo lại chữ ký đó một lần nữa! (có rất nhiều công cụ để làm điều đó) Trong trường hợp này, bạn cần lưu trữ khóa công khai của chữ ký của bạn ở đâu đó (như một tài nguyên) và sau đó so sánh nó với khoá công khai mới/hiện tại. more info here

+6

Chữ ký Authenticode được tạo bởi Signtool và đặt tên mạnh là hai thứ khác nhau. –

1

Tôi đã tìm kiếm github và tìm thấy Azure Microsoft C# code sử dụng đối tượng PowerShell để kiểm tra Chữ ký xác thực hợp lệ.

/// <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; 
    } 
Các vấn đề liên quan