You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows Server 2012 R2自签名证书生成与PEM导出报错解决

兼容Windows Server 2012及以上版本的自签名证书生成与PEM导出脚本

问题场景

在Windows Server 2016及以上系统中,可通过以下PowerShell脚本生成自签名证书并导出为PEM格式:

$cert = New-SelfSignedCertificate `
            -Subject "CN=$env:COMPUTERNAME,OU=xx,O=xx,C=xx" `
            -KeyAlgorithm RSA `
            -KeyLength 2048 `
            -KeyExportPolicy Exportable `
            -NotAfter (Get-Date).AddYears(3)

# 导出证书到文件
$CertBase64 = [System.Convert]::ToBase64String($cert.RawData, [System.Base64FormattingOptions]::InsertLineBreaks)
$Crt = @"
-----BEGIN CERTIFICATE-----
$CertBase64
-----END CERTIFICATE-----
"@
$Crt | Out-File -FilePath C:\cert.crt -Encoding Ascii

# 导出私钥到文件
$RSACng = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
$KeyBytes = $RSACng.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)
$KeyBase64 = [System.Convert]::ToBase64String($KeyBytes, [System.Base64FormattingOptions]::InsertLineBreaks)
$Key = @"
-----BEGIN PRIVATE KEY-----
$KeyBase64
-----END PRIVATE KEY-----
"@
$Key | Out-File -FilePath C:\cert.key -Encoding Ascii

# 清理证书存储
$cert | Remove-Item

但在Windows Server 2012 R2环境中,需将New-SelfSignedCertificate命令修改为:

$cert = New-SelfSignedCertificate `
    -DnsName "$env:COMPUTERNAME" `
    -CertStoreLocation cert:\LocalMachine\My

执行导出私钥的命令时会触发如下错误:

PS C:\> $KeyBytes = $RSACng.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)
Exception calling "Export" with "1" argument(s): "The requested operation is not supported.
"
At line:1 char:1
+ $KeyBytes = $RSACng.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]:: ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CryptographicException

由于无法使用OpenSSL等第三方工具,通过分析$cert.GetType()和$RSACng.GetType()输出,编写了兼容Windows Server 2012及以上版本的解决脚本(已修正原脚本语法错误):

if ([System.Environment]::OSVersion.Version -lt [Version]"10.0.14393.0") {   # 针对Windows Server 2012及以下版本生成自签名证书
  $policies = [System.Security.Cryptography.CngExportPolicies]::AllowPlaintextExport,[System.Security.Cryptography.CngExportPolicies]::AllowExport

  $name = new-object -com "X509Enrollment.CX500DistinguishedName.1"
  $name.Encode("CN=$env:COMPUTERNAME,OU=xxxx,O=yyyy S.p.A.,C=IT", 0)

  $key = new-object -com "X509Enrollment.CX509PrivateKey.1"
  $key.ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
  $key.KeySpec = 1
  $key.Length = 2048
  $key.SecurityDescriptor = "D:PAI(A;;0xd01f01ff;;;SY)(A;;0xd01f01ff;;;BA)(A;;0x80120089;;;NS)"
  $key.MachineContext = 1
  $key.ExportPolicy = [System.Security.Cryptography.CngExportPolicies]::AllowPlaintextExport
  $key.Create()

  $serverauthoid = new-object -com "X509Enrollment.CObjectId.1"
  $serverauthoid.InitializeFromValue("1.3.6.1.5.5.7.3.1")
  $ekuoids = new-object -com "X509Enrollment.CObjectIds.1"
  $ekuoids.add($serverauthoid)
  $ekuext = new-object -com "X509Enrollment.CX509ExtensionEnhancedKeyUsage.1"
  $ekuext.InitializeEncode($ekuoids)

  $cert = new-object -com "X509Enrollment.CX509CertificateRequestCertificate.1"
  $cert.InitializeFromPrivateKey(2, $key, "")
  $cert.Subject = $name
  $cert.Issuer = $cert.Subject
  $cert.NotBefore = get-date
  $cert.NotAfter = $cert.NotBefore.AddYears(10)
  $cert.X509Extensions.Add($ekuext)
  $cert.Encode()

  $enrollment = new-object -com "X509Enrollment.CX509Enrollment.1"
  $enrollment.InitializeFromRequest($cert)
  $certdata = $enrollment.CreateRequest(0)
  $enrollment.InstallResponse(2, $certdata, 0, "")

  $cert = Get-ChildItem Cert:\LocalMachine\My | where{$_.Subject -like "*xxxx*yyyy*"} 
} else {   # 针对Windows Server 2016及以上版本生成自签名证书
  $cert = New-SelfSignedCertificate -Subject "CN=$env:COMPUTERNAME,OU=xxxx,O=yyyy S.p.A.,C=IT" -KeyAlgorithm RSA -KeyLength 2048 -KeyExportPolicy Exportable -NotAfter (Get-Date).AddYears(10)
}

# 导出证书到文件
$CertBase64 = [System.Convert]::ToBase64String($cert.RawData, [System.Base64FormattingOptions]::InsertLineBreaks)
$Crt = @"
-----BEGIN CERTIFICATE-----
$CertBase64
-----END CERTIFICATE-----
"@
$Crt | Out-File -FilePath C:\abc.crt -Encoding Ascii

# 导出私钥到文件
$RSACng = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($cert)
$KeyBytes = $RSACng.Key.Export([System.Security.Cryptography.CngKeyBlobFormat]::Pkcs8PrivateBlob)
$KeyBase64 = [System.Convert]::ToBase64String($KeyBytes, [System.Base64FormattingOptions]::InsertLineBreaks)
$Key = @"
-----BEGIN PRIVATE KEY-----
$KeyBase64
-----END PRIVATE KEY-----
"@
$Key | Out-File -FilePath C:\abc.key -Encoding Ascii

# 清理证书存储
$cert | Remove-Item

内容的提问来源于stack exchange,提问作者vb8448

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:35:57