自动导出x509证书w / chain从Server 2008 R2到没有外部工具的p7b文件?

时间:2015-11-04 01:54:05

标签: powershell x509 pkcs#7 certutil

我集中管理域控制器,但站点管理员在本地管理自己的数字发送器。我可以通过向导轻松地将整个链中的X509证书(不需要私钥)从Windows Server 2008 R2域控制器导出到p7b文件:

~~~~~~~~~~~~~~~~~

... 5。 “证书导出向导”将打开。单击“下一步”。

  1. 在“导出文件格式”对话框中,执行以下操作:

    一个。选择加密消息语法标准 - PKCS#7证书(.P7B)。

    湾如果可能,请选中包含证书路径中的所有证书。

    ℃。单击“下一步”。

  2. 在“要导出的文件”对话框中,单击“浏览”。

  3. 在“另存为”对话框中,执行以下操作:

    一个。在“文件名”框中,键入ciroots.p7b。

    湾在“保存类型”框中,选择PKCS#7证书(* .p7b)。

    ℃。单击“保存”。

  4. 在“要导出的文件”对话框中,单击“下一步”。

  5. 在“完成证书导出向导”页上,单击“完成”。

  6. ~~~~~~~~~~~~~~~~~

    效果很好。生成的文件可以很好地导入数字发送器进行身份验证。它为站点管理员提供了访问链中其他证书的权限(如果他们尚未导入它们)。它不需要包含私钥,因为它没有它就可以正常工作。

    麻烦的是,我需要手动执行此操作,几十次,每个业务站点一次,因为每个都有自己的域控制器,每个域控制器都有自己的证书。必须有一种方法可以自动执行此证书导出(PowerShell w / .NET,certutil.exe等)。也许是使用System.Security.Cryptography.X509Certificates X509IncludeOption和WholeChain的东西,但是我无法使它工作:

    $ Cert =(dir Cert:\ localmachine \ my)[0]

    #PKCS7 cert export with .p7b文件扩展名。

    $ CertCollection = New-Object

    System.Security.Cryptography.X509Certificates.X509Certificate2Collection

    $ Cert | %{[空隙] $ CertCollection.Add($ _)}

    $ Exported_pkcs7 = $ CertCollection.Export(' Pkcs7')

    $ out_FileName = $ ENV:COMPUTERNAME +" .p7b"

    $ My_Export_Path =' d:\ CertFiles \' + $ out_FileName

    Set-Content -path $ My_Export_Path -Value $ Exported_pkcs7 -encoding Byte

    使用此代码,我只获得证书,而不是其链中的其他证书。我不需要整个脚本,只需要复制导出w /链的部分,我已经可以通过GUI手动完成。

2 个答案:

答案 0 :(得分:4)

您需要构建证书链以获取链证书并将其添加到集合中:

function Export-Certificate {
[CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [Security.Cryptography.X509Certificates.X509Certificate2]$Certificate,
        [Parameter(Mandatory = $true)]
        [IO.FileInfo]$OutputFile,
        [switch]$IncludeAllCerts
    )
    $certs = New-Object Security.Cryptography.X509Certificates.X509Certificate2Collection
    if ($IncludeAllCerts) {
        $chain = New-Object Security.Cryptography.X509Certificates.X509Chain
        $chain.ChainPolicy.RevocationMode = "NoCheck"
        [void]$chain.Build($Certificate)
        $chain.ChainElements | ForEach-Object {[void]$certs.Add($_.Certificate)}
        $chain.Reset()
    } else {
        [void]$certs.Add($Certificate)
    }
    Set-Content -Path $OutputFile.FullName -Value $certs.Export("pkcs7") -Encoding Byte
}

答案 1 :(得分:0)

已经发布了很多时间,但这对您有所帮助。 我对脚本进行了一些改进,以便进行流水线化并添加了帮助。

function Export-CertificateChain {
<#
.SYNOPSIS
    Create p7b certificate container.
.DESCRIPTION
    Create p7b certificate container.
.EXAMPLE
    PS C:\> ls "C:\PKI Trust Chain\Certificates" -File -Recurse | Get-PfxCertificate | where issuer -match 'Internal|External' | Export-CertificateChain -OutputFile C:\Temp\PKITrustChain.p7b
    Loop thru the folder "C:\PKI Trust Chain\Certificates" (assuming it contains only certificates), load the certficiates and add all certificates where issuer matches into the p7b file. 
.EXAMPLE
    PS C:\> ls "cert:\localMachine\" -Recurse | where issuer -match 'Internal|External' | Export-CertificateChain -OutputFile C:\Temp\PKITrustChain.p7b
    Loop thru the certificate stroe where issuer matches and adds them into the p7b file. 
.INPUTS
    [Security.Cryptography.X509Certificates.X509Certificate2], [IO.FileInfo]
.OUTPUTS
    None.
.NOTES
Author: Patrick Sczepanski  (Vadims Podans)
Original script found: https://stackoverflow.com/questions/33512409/automate-export-x509-certificate-w-chain-from-server-2008-r2-to-a-p7b-file-witho
Version: 20200505
#>
    [CmdletBinding()]
    param(
        # certificate to add to p7b file
        [Parameter(Mandatory = $true, ValueFromPipeline=$true)]
        [Security.Cryptography.X509Certificates.X509Certificate2]$Certificate,
        # path an name of the p7b container
        [Parameter(Mandatory = $true)]
        [IO.FileInfo]$OutputFile,
        # automatically add the trust chain for each certificate. Requires the trust chain being available.
        [switch]$IncludeAllCerts
    )
    Begin{
        $certs = New-Object Security.Cryptography.X509Certificates.X509Certificate2Collection
    }
    Process {
        if ($IncludeAllCerts) {
            $chain = New-Object Security.Cryptography.X509Certificates.X509Chain
            $chain.ChainPolicy.RevocationMode = "NoCheck"
            [void]$chain.Build($Certificate)
            $chain.ChainElements | ForEach-Object {[void]$certs.Add($_.Certificate)}
            $chain.Reset()
        } else {
            [void]$certs.Add($Certificate)
        }
    }
    End {
        Set-Content -Path $OutputFile.FullName -Value $certs.Export("pkcs7") -Encoding Byte
    }
}