Как проверить подлинность для Javascript в C#

Мне удалось подписать JS-файл с помощью PowerShell Set-AuthenticodeSignature. После этого я вижу подпись в файле в виде:

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

Я могу проверить подпись с помощью Get-AuthenticodeSignature. Он говорит, что sig действителен, но я не могу найти способ проверить подпись в коде C#. Все эти варианты не удалось:

  1. X509Certificate.CreateFromSignedFile
  2. X509Certificate object C# альтернатива производительности и памяти - исправлено
  3. Используется WinVerifyTrust от Wintrust.dll
  4. Портированная часть Get-AuthenticodeSignature из PowerShell!

Может быть, есть некоторые конкретные API для проверки подписи JS?

2 ответа

Недавно я столкнулся с подобной проблемой, и позвольте мне показать, что я сделал, чтобы решить эту проблему. Прежде чем я уйду, я сделаю несколько предположений. Пожалуйста, поправьте меня, если я ошибаюсь.

  1. wintrust работает для всех других случаев, кроме файлов сценариев, таких как.js или.vbs
  2. Возможно, вы пытались "wintrustverify" из консольного приложения (C#)

Я понял, что это происходит только с файлами сценариев, как я уже упоминал выше, потому что wintrust ведет себя странно, когда его методы выполняются из модели многопоточных квартир (MTA). Как только это было обернуто в нити STA, это начало работать для меня. Позже я узнал, что это историческая проблема, что мы должны были принять меры предосторожности, когда имеем дело с любыми взаимодействиями COM-компонентов из приложения.Net.

Вот фрагмент кода, вы можете заменить верифицируемую подпись логикой кода wintrust и попробовать. Надеюсь, это поможет.

            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;
                }
            }

WinVerifyTrust поддерживает проверку файлов, отличных от исполняемых файлов, с помощью флага WTD_CHOICE_BLOB. Убедитесь, что вы предоставили структуру WINTRUST_BLOB_INFO с правильным пакетом предметного интерфейса (SIP). Из того, что я вижу, команда Get-AuthenticodeSignature использует PowerShell SIP {603bcc1f-4b59-4e08-b724-d2c6297ef351} для проверки подписи. Я предполагаю, что Set-AuthenticodeSignature использует тот же SIP для подписи скрипта.

Другие вопросы по тегам