首页 > 解决方案 > 可以将对文件路径的 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

第一个字段需要一个文本字符串(Issuing Authortiy) - 很简单。

其余三个字段应该采用基于文本的文件,并且在用变量替换时将不起作用。前两个参数($arg2a 和 $arg3)是输入(作为文本文件) 最后一个参数($arg4)是输出。除非我将其设为文件位置(例如“c:\temp\outfile.csr”),否则它将始终打开一个用于保存位置的 gui 提示

有没有一种方法可以欺骗 certutil 使其相信它正在适当地从文本文件接收/发送到文本文件,以便我可以将信息保存在对象中以供进一步操作?

显然,我可以将输入和输出写入系统临时目录中的文件并读回数据,但最好不必这样做。

非常感谢

标签: powershellcertutil

解决方案


正如我在评论中提到的那样,我从来没有找到一种方法来做到这一点,但我确实设法将一个不调用命令行工具的函数拼凑在一起。

注意:这在生产中运行可能不安全。

它主要来自: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
      }
   }
}

推荐阅读