OpenSSL pkcs12 单独导出链式 CA 证书

OpenSSL pkcs12 Export chained CA Certs separately

我有一个如下所示的证书链:

我正在使用 openssl.exe 从 MyCert.pfx 创建 .cer 文件,我希望生成的证书首先包含客户端证书,然后是中间 CA 证书。最终结果应如下所示:

Bag Attributes
  <mycert attributes>

-----BEGIN CERTIFICATE-----
  <mycert data>
-----END CERTIFICATE-----  

Bag Attributes
  <intermediate ca attributes>

-----BEGIN CERTIFICATE-----
  <intermediate ca data>
-----END CERTIFICATE-----  

我可以通过 运行ning

获得第一个证书
openssl pkcs12 -in MyCert.pfx -clcerts -nokeys -password pass:mypassword -out mycert.cer

而且我可以 运行 像这样在链中获取 CA 证书的命令

openssl pkcs12 -in MyCert.pfx -cacerts -nokeys -password pass:mypassword -out cacert.cer

但这会生成一个包含全局 CA 和中间 CA 证书的文件。

有没有办法通过 CN 或其他方式仅指定中间 CA?

我可以从文件中获取内容,但希望有一个更简洁的解决方案。

好吧,我选择了粗暴的方式......就是这样。

# Generate the client cert
&"$opensslPath\openssl.exe" pkcs12 -in "$($filepathforCert).pfx" -clcerts -nokeys -out "$($filepathforCert)-fullchain.crt" -password pass:$certPassword

# Generate the CA certs in the chain
&"$opensslPath\openssl.exe" pkcs12 -in "$($filepathforCert).pfx" -cacerts -nokeys -out "$($filepathforCACert).crt" -password pass:$certPassword


# Combine certs
# The common name for the intermediate CA should be the same until 2031
$intermediateCaCn = "CN = DigiCert TLS RSA SHA256 2020 CA1"
$certBeginToken = "-----BEGIN CERTIFICATE-----"
$certEndToken = "-----END CERTIFICATE-----"

$intermediateCACertStart = (Select-String -Pattern $intermediateCaCn -Path "$($filepathforCACert).crt" -SimpleMatch | select-object -First 1).LineNumber
$firstCertStart = (Select-String -Pattern $certBeginToken -Path "$($filepathforCACert).crt" -SimpleMatch | select-object -First 1).LineNumber

$intermediateStartLine = 0
$intermediateEndLine = 0

# The beginning of the cert will always start after the CN
if($intermediateCACertStart -gt $firstCertStart)
{
    $intermediateStartLine = (Select-String -Pattern $certBeginToken -Path "$($filepathforCACert).crt" -SimpleMatch | select-object -Last 1).LineNumber
    $intermediateEndLine = (Select-String -Pattern $certEndToken -Path "$($filepathforCACert).crt" -SimpleMatch | select-object -Last 1).LineNumber
}
else
{
    $intermediateStartLine = $firstCertStart
    $intermediateEndLine = (Select-String -Pattern $certEndToken -Path "$($filepathforCACert).crt" -SimpleMatch | select-object -First 1).LineNumber
}

# size of the cert, including the delimiters
$lineCount = ($intermediateEndLine - $intermediateStartLine)

$certContent = (Get-Content -Path "$($filepathforCACert).crt"| Select-Object -Skip ($intermediateStartLine - 1) -First ($lineCount +1))

Add-Content -Path "$($filepathforCert)-fullchain.crt" -Value $certContent