powershell - 使用 Root CA Signer 生成自签名证书

标签 powershell sql-server-2012 windows-server-2012-r2

场景:我在 Windows Server 2012r2 上使用 PowerShell 生成根证书,并希望使用它在动态生成(和销毁)的开发/测试环境中签署新创建的中间证书和 Web 证书。这些脚本是远程部署的,目的是尽可能保持纯 PowerShell。在 Windows 10/2016 中,这相对容易,生成根证书后:

$Cert = New-SelfSignedCertificate -Signer $Root -Subject "CN=$Subject"

我使用 COM X509Enrollment.CX509CertificateRequestCertificate 生成了根证书和 Security.Cryptography.X509Certificates.X509Certificate2在我已经有一段时间的 SCSS PS 中,主要是因为我需要确保主题和用法设置得非常具体。如果没有上述内容(我以前使用过),我不太确定如何使用它来签署标准证书。

在 C# 中有一些使用 Bouncy CaSTLe(见下文)的示例,我可以将其绑定(bind)到 PowerShell,但是我需要在动态开发/测试环境中另外部署它,并且我希望能够在 Powershell 中执行此操作(通过 COM如果需要)具有最少的依赖关系。
  • C# Generate Self Signed Certificates on the Fly
  • How do I use Bouncy Castle in Powershell
  • 最佳答案

    就我而言,避免 makecert 和 openssl 的最终解决方案是使用 Powershell 和 BouncyCaSTLe。我从 PSBouncyCastle fork 了 PSBouncyCaSTLe 存储库由 RLipscombe 发布并插入 1.8.1 Bouncy CaSTLe。我的 fork 版本是我用于脚本的版本, fork 位于 Forked: PSBouncyCastle.New .

    然后我使用了StackOverflow: C# Generate Certificates on the Fly作为在下面编写以下 powershell 的灵感,我将把它添加到我的 GitHub 并发表评论,我会尽快修改它 :

    Import-Module -Name PSBouncyCastle.New
    
    function New-SelfSignedCertificate {
      [CmdletBinding()]
      param (
        [string]$SubjectName,
        [string]$FriendlyName = "New Certificate",
        [object]$Issuer,
        [bool]$IsCA = $false,
        [int]$KeyStrength = 2048,
        [int]$ValidYears = 2,
        [hashtable]$EKU = @{}
      )
    
      # Needed generators
      $random = New-SecureRandom
      $certificateGenerator = New-CertificateGenerator
    
      if($Issuer -ne $null -and $Issuer.HasPrivateKey -eq $true)
      {
        $IssuerName = $Issuer.IssuerName.Name
        $IssuerPrivateKey = $Issuer.PrivateKey
      }
      # Create and set a random certificate serial number
      $serial = New-SerialNumber -Random $random
      $certificateGenerator.SetSerialNumber($serial)
    
      # The signature algorithm
      $certificateGenerator.SetSignatureAlgorithm('SHA256WithRSA')
    
      # Basic Constraints - certificate is allowed to be used as intermediate.
      # Powershell requires either a $null or reassignment or it will return this from the function
      $certificateGenerator = Add-BasicConstraints -isCertificateAuthority $IsCA -certificateGenerator $certificateGenerator
    
      # Key Usage
      if($EKU.Count -gt 0) 
      {
        $certificateGenerator = $certificateGenerator | Add-ExtendedKeyUsage @EKU
      }
      # Create and set the Issuer and Subject name
      $subjectDN = New-X509Name -Name ($SubjectName)
      if($Issuer -ne $null) {
        $IssuerDN = New-X509Name -Name ($IssuerName)
      }
      else 
      {
        $IssuerDN = New-X509Name -Name ($SubjectName)
      }  
      $certificateGenerator.SetSubjectDN($subjectDN)
      $certificateGenerator.SetIssuerDN($IssuerDN)
    
      # Authority Key and Subject Identifier
      if($Issuer -ne $null)
      {
        $IssuerKeyPair = ConvertTo-BouncyCastleKeyPair -PrivateKey $IssuerPrivateKey
        $IssuerSerial = [Org.BouncyCastle.Math.BigInteger]$Issuer.GetSerialNumber()
        $authorityKeyIdentifier = New-AuthorityKeyIdentifier -name $Issuer.IssuerName.Name -publicKey $IssuerKeyPair.Public -serialNumber $IssuerSerial
        $certificateGenerator = Add-AuthorityKeyIdentifier -certificateGenerator $certificateGenerator -authorityKeyIdentifier $authorityKeyIdentifier
      }
    
      # Validity range of the certificate
      [DateTime]$notBefore = (Get-Date).AddDays(-1)
      if($ValidYears -gt 0) {
        [DateTime]$notAfter = $notBefore.AddYears($ValidYears)
      }
      $certificateGenerator.SetNotBefore($notBefore)
      $certificateGenerator.SetNotAfter($notAfter)
    
    
      # Subject public key ~and private
      $subjectKeyPair = New-KeyPair -Strength $keyStrength -Random $random
      if($IssuerPrivateKey -ne $null)
      {
        $IssuerKeyPair = [Org.BouncyCastle.Security.DotNetUtilities]::GetKeyPair($IssuerPrivateKey)
      }
      else 
      {
        $IssuerKeyPair = $subjectKeyPair
      }
      $certificateGenerator.SetPublicKey($subjectKeyPair.Public)
    
      # Create the Certificate
      $IssuerKeyPair = $subjectKeyPair
      $certificate = $certificateGenerator.Generate($IssuerKeyPair.Private, $random)
      # At this point you have the certificate and need to convert it and export, I return the private key for signing the next cert
      $pfxCertificate = ConvertFrom-BouncyCastleCertificate -certificate $certificate -subjectKeyPair $subjectKeyPair -friendlyName $FriendlyName
      return $pfxCertificate
    }
    

    此 powershell 的一些使用示例如下:

    生成根 CA
    $TestRootCA = New-SelfSignedCertificate -subjectName "CN=TestRootCA" -IsCA $true
    Export-Certificate -Certificate $test -OutputFile "TestRootCA.pfx" -X509ContentType Pfx
    

    生成标准自签名
    $TestSS = New-SelfSignedCertificate -subjectName "CN=TestLocal"
    Export-Certificate -Certificate $TestSS -OutputFile "TestLocal.pfx" -X509ContentType Pfx
    

    生成证书,使用根证书签名
    $TestRootCA = New-SelfSignedCertificate -subjectName "CN=TestRootCA" -IsCA $true
    $TestSigned = New-SelfSignedCertificate -subjectName "CN=TestSignedByRoot" -issuer $TestRootCA
    
    Export-Certificate -Certificate $test -OutputFile "TestRootCA.pfx" -X509ContentType Pfx
    Export-Certificate -Certificate $test -OutputFile "TestRootCA.pfx" -X509ContentType Pfx
    

    生成具有特定用途的自签名
    $TestServerCert = New-SelfSignedCertificate -subjectName "CN=TestServerCert" -EKU @{ "ServerAuthentication" = $true }
    

    请注意,-EKU 参数通过 splatting 接受,它这样做是为了确保添加到 Add-ExtendedKeyUsage 的任何内容都被有效传递。它接受以下证书用法:
  • 数字签名
  • 不可否认
  • key 加密
  • 数据加密
  • 关键协议(protocol)
  • KeyCertSign
  • CrlSign
  • 仅加密
  • 仅解密

  • 这符合我的需要,并且似乎适用于我们用于动态环境的所有 Windows 平台。

    关于powershell - 使用 Root CA Signer 生成自签名证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44004052/

    相关文章:

    powershell - Get-ChildItem递归作为PowerShell中的参数

    c# - C# 托管的 Powershell 中的内存泄漏

    SQL Coldfusion - 搜索重复名称时消除单词 THE

    sql-server-2012 - 关于使用 NVARCHAR(MAX)

    c# - 如何与同一台机器上的其他用户共享 SQL LocalDb?

    iis - Bonobo Git 服务器配置 : HTTP Error 500. 19 - 第 71 行内部服务器错误

    c# - PowerShell 中内联 C# 中的 ScriptBuilder(2.0 及更高版本)

    powershell - 使用 powershell 在远程服务器上安装 pfx 证书

    windows - 如何测试Windows Server是否完全更新? (尝试创建更新/重启循环脚本)

    c# - 如何解决 Microsoft SQL Server。错误 233。提供商 : SSL Provider