我能够使用PowerShell Set-AuthenticodeSignature签名js文件。
之后,我可以看到签名以以下形式出现在文件中:
// SIG // Begin signature block
// SIG // MIIKgAYJKoZIhvcNAQcCoIIKcTCCCm0CAQExCzAJBgUr
// SIG // ....
// SIG // End signature block
我可以使用Get-AuthenticodeSignature验证签名。它说sig是有效的,但是我找不到在C#代码中验证签名的方法。
所有这些选项均失败:
也许有一些特定的API可以验证JS签名?
最佳答案
最近,我遇到了类似的问题,让我展示解决该问题的方法。在我开始之前,我现在很少有假设。如果我错了,请纠正我。
.js或.vbs
控制台应用程序(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;
}
}