2016-12-14 47 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; 
       } 
      }