我能够使用PowerShell Set-AuthenticodeSignature签名js文件。
之后,我可以看到签名以以下形式出现在文件中:

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

我可以使用Get-AuthenticodeSignature验证签名。它说sig是有效的,但是我找不到在C#代码中验证签名的方法。
所有这些选项均失败:
  • X509Certificate.CreateFromSignedFile
  • X509Certificate object c# performance and memory issues alternative – fixed
  • 从Wintrust.dll使用的WinVerifyTrust
  • 从PowerShell移植了Get-AuthenticodeSignature的一部分!

  • 也许有一些特定的API可以验证JS签名?

    最佳答案

    最近,我遇到了类似的问题,让我展示解决该问题的方法。在我开始之前,我现在很少有假设。如果我错了,请纠正我。

  • wintrust适用于脚本文件以外的所有其他情况
    .js或.vbs
  • 您可能已经尝试从一个“wintrustverify”
    控制台应用程序(C#)

  • 我发现这种情况只发生在上面提到的脚本文件中,因为从自由线程单元模型(MTA)执行wintrust的方法时,wintrust的行为会异常。一旦将其包装在STA线程中,它便开始为我工作。后来我才知道这是一个历史问题,当我们处理来自.Net应用程序的任何COM组件互操作时,我们应该采取预防措施。

    这是代码段,您可以使用wintrust代码逻辑替换verifySignature并尝试。我希望这有帮助。
                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;
                    }
                }
    

    09-15 15:58