2016-12-14 63 views
1

我能夠使用PowerShell Set-AuthenticodeSignature簽署js文件。 後,我能看到的簽名出現在文件中的形式:如何在C#中驗證Javascript的authenticode#

// SIG // Begin signature block 
// SIG // MIIKgAYJKoZIhvcNAQcCoIIKcTCCCm0CAQExCzAJBgUr 
// SIG // .... 
// SIG // End signature block 

我可以使用Get-AuthenticodeSignature驗證簽名。它說,sig是有效的,但我無法找到一種方法來驗證C#代碼中的簽名。 所有這些選項失敗:

  1. X509Certificate.CreateFromSignedFile
  2. X509Certificate object c# performance and memory issues alternative – fixed
  3. 從PowerShell中使用來自的WinVerifyTrust Wintrust.dll
  4. 獲取-AuthenticodeSignature的閥塊的一部分!

也許有一些具體的apis來驗證js簽名?

回答

1

WinVerifyTrust支持使用WTD_CHOICE_BLOB標誌驗證可執行文件以外的文件。確保你提供的WINTRUST_BLOB_INFO結構的正確subject interface package(SIP)。從我所看到的,Get-AuthenticodeSignature命令使用PowerShell SIP {603bcc1f-4b59-4e08-b724-d2c6297ef351}來驗證簽名。我假設Set-AuthenticodeSignature使用相同的SIP來簽署腳本。

+0

感謝您指出這一點。我檢查過,使用了WTD_CHOICE_BLOB,但驗證後它返回0x800b0100(無簽名)。但簽名在文件中。這裏blob正在初始化https://github.com/PowerShell/PowerShell/blob/309bf603f9aff9009dce7e725d42b2d4f99f58c9/src/System.Management.Automation/security/Authenticode.cs#L529。使用File.ReadAllText將文件加載到內存中。 –

+0

仔細看看你是否也嘗試提供一個文件路徑(所以用WINTRUST_FILE_INFO代替) – erikvdv1

+0

對不起,按下輸入太快了......仔細看看[Get-AuthenticodeSignature](https://github.com/ PowerShell/PowerShell/blob/309bf603f9aff9009dce7e725d42b2d4f99f58c9/src/Microsoft.PowerShell.Security/security/SignatureCommands.cs#L281)顯示fileContent == null,因此使用WINTRUST_FILE_INFO。你嘗試過嗎? – erikvdv1

1

我最近遇到了類似的問題,讓我說明我做了什麼來解決這個問題。在我走之前,我現在做的假設很少。如果我錯了,請糾正我。

  1. wintrust工作比腳本文件,如 的.js或者.VBS
  2. 可能嘗試從 控制檯應用程序 「wintrustverify」(C#)

我想通以外的所有其他情況它出現這種情況只會發生在上面提到的腳本文件中,因爲wintrust在從自由線程單元模型(MTA)執行它的方法時表現得很粗糙。一旦它被包裝在一個STA線程中,它就開始爲我工作。後來我才知道這是一個歷史問題,我們應該在處理來自.Net應用程序的任何COM組件互操作時採取預防措施。

以下是代碼片段,您可以用您的wintrust代碼邏輯代替verifyysignature並嘗試。我希望這有幫助。

  public static void CheckSignature() 
      { 
       STAApartment apt = new STAApartment(); 
       var result = apt.Invoke(() => 
       { 
        return VerifySignature(@".\signedjsfile.js", false); 
       }); 
       Console.WriteLine(result); 
      } 

      private static WinVerifyTrustResult VerifySignature(string filePath, bool verifySignatureOnly) 
      { 

       using (var wtd = new WinTrustData(new WinTrustFileInfo(filePath)) 
       { 
        dwUIChoice = WintrustUIChoice.WTD_UI_NONE, 
        dwUIContext = WinTrustDataUIContext.WTD_DATA_UI_EXECUTE, 
        fdwRevocationChecks = WinTrustDataRevocationChecks.WTD_REVOCATION_CHECK_WHOLECHAIN, 
        dwStateAction = WintrustAction.WTD_STATEACTION_IGNORE, 
        dwProvFlags = verifySignatureOnly ? WintrustProviderFlags.WTD_HASH_ONLY_FLAG : WintrustProviderFlags.WTD_REVOCATION_CHECK_CHAIN 
       }) 
       { 
        var result = WinTrust.WinVerifyTrust(
         WinTrust.INVALID_HANDLE_VALUE, new Guid(WinTrust.WINTRUST_ACTION_GENERIC_VERIFY_V2), wtd 
        ); 
        return result; 
       } 
      } 

      public class STAApartment 
      { 
       public T Invoke<T>(Func<T> func) 
       { 
        var tcs = new TaskCompletionSource<T>(); 
        Thread thread = new Thread(() => 
        { 
         try 
         { 
          tcs.SetResult(func()); 
         } 
         catch (Exception e) 
         { 
          tcs.SetException(e); 
         } 
        }); 
        thread.SetApartmentState(ApartmentState.STA); 
        thread.Start();     
        return tcs.Task.Result; 
       } 
      }