Можно ли перенаправить запрос certutil для пути к файлу в переменную powershell?

Я использую утилиту командной строки certreq, чтобы сформулировать поправку CSR следующим образом (я упростил синтаксис для ясности)

$CertReqPath = "C:\Windows\System32\certreq.exe"
$arg1="-config"
$arg1a= $IssuingCA
$arg2="-policy"
$arg2a= $CSR
$arg3=$Inf
$arg4=$NewSANCSR

& $CertReqPath $arg1 $arg1a $arg2 $arg2a $arg3 $arg4

Первое поле требует текстовой строки (выдающий орган) - достаточно просто.

Остальные три поля должны принимать текстовый файл и не будут работать при замене переменной. Первые два аргумента ($ arg2a и $ arg3) являются входными данными (в виде текстовых файлов) Последний аргумент ($ arg4) - это вывод. Он всегда будет открывать приглашение графического интерфейса пользователя для места сохранения, если я не сделаю его местом для файла (например, "c: \ temp \ outfile.csr")

Есть ли способ заставить certutil поверить, что он получает / отправляет текстовый файл в зависимости от ситуации, чтобы я мог сохранить информацию в объекте для дальнейших манипуляций?

Очевидно, я могу записывать входные и выходные данные в файл в системном временном каталоге и считывать данные обратно, но было бы предпочтительнее этого не делать.

Большое спасибо

Я пытался сделать то же самое несколько лет назад. Работал много месяцев, но так и не нашел решения.

WayneA 10.08.2018 21:53
0
1
547
1

Ответы 1

Как я упоминал в своем комментарии, я так и не нашел способа сделать это, но мне удалось скомпрометировать функцию, которая не вызывала инструменты командной строки.

Примечание. Запускать это в производственной среде может быть небезопасно.

В основном это взято из: https://blogs.msdn.microsoft.com/alejacma/2008/09/05/how-to-create-a-certificate-request-with-certenroll-and-net-c/

Function New-CertificateFromCA{
   [CmdletBinding()]
   Param (

      [String[]]$CommonName = @([System.Net.Dns]::GetHostEntry($env:computerName).hostname),

      [string]$OrganizationalUnit = "CustomOUname",

      [string]$Organization = "YourOrganizationHere",

      [string]$City = "YourCityHere",

      [string]$State = "YourStateHere",

      [string]$Country = "YourCountryHere",

      [int]$KeyLength = 4096,

      [string]$ProviderName = "Microsoft Enhanced Cryptographic Provider v1.0",

      [string]$TemplateName = "YourTemplateHere",

      [string]$CertificateAuthority = $null

   )

   begin {
      # contexts
      New-Variable -Name UserContext -Value 0x1 -Option Constant
      New-Variable -Name MachineContext -Value 0x2 -Option Constant
      # installation options
      New-Variable -Name AllowNone -Value 0x0 -Option Constant
      New-Variable -Name AllowNoOutstandingRequest -Value 0x1 -Option Constant
      New-Variable -Name AllowUntrustedCertificate -Value 0x2 -Option Constant
      New-Variable -Name AllowUntrustedRoot -Value 0x4 -Option Constant
      # encoding
      New-Variable -Name Base64Header -Value 0x0 -Option Constant
      New-Variable -Name Base64 -Value 0x1 -Option Constant
   }

   Process {
      [string]$Subject = "CN=$($CommonName), OU=$($OU), O=$($Organization), L=$($City), S=$($State), C=$($Country)"

      $objCSP = New-Object -ComObject "X509Enrollment.CCspInformation"
      $objCSP.InitializeFromName($ProviderName)

      $objCSPs = New-Object -ComObject "X509Enrollment.CCspInformations"
      $objCSPs.Add($objCSP)

      $objPrivateKey = new-Object -ComObject "X509Enrollment.CX509PrivateKey"
      $objPrivateKey.Length = $KeyLength
      $objPrivateKey.KeySpec = 2 #X509KeySpec.XCN_AT_SIGNATURE
      $objPrivateKey.KeyUsage = 16777215 #0xffffff #X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES
      $objPrivateKey.MachineContext = $True
      $objPrivateKey.CspInformations = $objCSPs
      $objPrivateKey.ExportPolicy = 1 #Exportable
      $objPrivateKey.Create()

      $objPkcs10 = New-Object -ComObject X509Enrollment.CX509CertificateRequestPkcs10
      $objPkcs10.InitializeFromPrivateKey(2, $objPrivateKey, "$TemplateName")


      $objAlternativeName = New-Object -ComObject "X509Enrollment.CAlternativeName"
      $objAlternativeName.InitializeFromString(3, $CommonName)

      $objAlternativeNames = New-Object -ComObject "X509Enrollment.CAlternativeNames"
      $objAlternativeNames.Add($objAlternativeName)

      $objExtensionAlternativeNames = New-Object -ComObject "X509Enrollment.CX509ExtensionAlternativeNames"
      $objExtensionAlternativeNames.InitializeEncode($objAlternativeNames)
      $objPkcs10.X509Extensions.Add($objExtensionAlternativeNames)

      $objDN = New-Object -ComObject "X509Enrollment.CX500DistinguishedName"
      $objDN.Encode($Subject, 0)
      $objPkcs10.Subject = $objDN

      # Enroll locally
      $objEnroll = new-object -com "X509Enrollment.CX509Enrollment"
      $objEnroll.InitializeFromRequest($objPkcs10)
      $DERString = $objEnroll.CreateRequest(0x1)

      # Identify and Submit to CA
      $CAQuery = certutil -templateCAs $TemplateName
      If ($CAQuery -match "completed successfully") { $strCAConfig = $CAQuery[0] }

      $objCertRequest = New-Object -ComObject "CertificateAuthority.Request"
      $intDisposition = $objCertRequest.Submit(1, $DERString, $null, $strCAConfig)

      If ($intDisposition -eq 3) {
         Write-Verbose "Request Submitted successfully"
         $strCert = $objCertRequest.GetCertificate(257)
         $objEnroll = new-object -com "X509Enrollment.CX509Enrollment"
         $objEnroll.Initialize($MachineContext)
         $objEnroll.InstallResponse($AllowUntrustedRoot, $strCert, $Base64, $null)
         $Flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
         $Flags = $Flags -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet
         $Flags = $Flags -bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet

         $Cert = New-Object Security.Cryptography.X509Certificates.X509Certificate2
         $Cert.Import([System.Convert]::FromBase64String($objEnroll.Certificate(1)),$null,$Flags)
         $result = gci -Recurse cert:\*$($Cert.Thumbprint)
         Write-Verbose "Certificate with thumbprint $($Cert.Thumbprint) installed"
         $result
      }
   }
}

Хорошо, по крайней мере, я знаю, это не простая вещь - я так много подозревал. Теперь есть модуль PSPKI Powershell для простых запросов, но здесь я добавляю сети SAN с помощью сертификата агента регистрации. Я рассмотрю этот способ сделать это, если у меня будет время, иначе просто продолжайте использовать системный временный каталог, спасибо

Scepticalist 12.08.2018 10:01

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