2016-12-14 4 views
1

Я смог подписать файл js с помощью PowerShell Set-AuthenticodeSignature. После этого я могу увидеть подпись появилась в файле в виде:Как проверить подлинность для Javascript в C#

// 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. Используется WinVerifyTrust от Wintrust.dll
  4. портирована часть Get-AuthenticodeSignature из PowerShell!

Возможно, существует определенная ошибка для проверки подписи 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

Извините, нажал enter слишком быстро ... Познакомьтесь с [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, он начал работать для меня. Позже я узнал, что это исторический вопрос, который мы должны были принять меры предосторожности, когда мы имеем дело с любыми взаимодействиями COM-компонентов из приложения .Net.

Вот фрагмент кода, вы можете заменить verifysignature логикой кода 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; 
       } 
      } 
Смежные вопросы