首页 > 解决方案 > 在不使用外部程序或库的情况下使用 Windows PowerShell/.Net 创建证书和 CSR

问题描述

我想创建一个私钥和一个 CSR,将 CSR 提交给证书颁发机构,在颁发证书后检索证书,并将私钥和证书作为单独的 PEM 文件适用于非 Microsoft 应用程序(它们通常是 web服务器)。我想避免使用 Java Keytool 或 OpenSSL 在 Windows Server 2016 上的 Windows PowerShell 中生成密钥和证书签名请求。CSR 将提交给 Microsoft Active Directory 证书服务。

OpenSSL 和 Java 没有(也不会)安装在需要证书的计算机上。由于证书适用于非 Microsoft 应用程序,因此我还想避免在计算机上使用证书存储。我不介意使用“certreq”来实际提交完整的 CSR 并在获得批准后检索生成的证书。

我有一些代码,基于C# Export Private/Public RSA key from RSACryptoServiceProvider to PEM string,它将从 X509Certificate2 中提取私钥。到目前为止,作为一个实验,我已经成功地将它与 PKCS12 密钥库一起使用(其中密钥和 CSR 是使用 Keytool 创建的)。

自动化在 .NET Core 中创建私钥、CSR 和最终签名证书的过程的启发,我拼凑了以下内容,但没有灵感,也不知道自己在做什么。如何完成将 CSR 提交给 CA(或将 CSR 作为文件输出以与 certreq 一起使用)的过程?

[int]$KeyLength = 2048
$ComputerName = "jon"
$Domain = "domain.local"
[string]$DistinguishedName = "CN=$($ComputerName).$($Domain),OU=Unit,O=Org,C=GB"
$HashAlgo = [System.Security.Cryptography.HashAlgorithmName]::SHA256
$RSASigPadding = [System.Security.Cryptography.RSASignaturePadding]::Pkcs1

$RSAKey = [System.Security.Cryptography.RSA]::Create($KeyLength)
$Certificate = [System.Security.Cryptography.X509Certificates.CertificateRequest]::new($DistinguishedName,$RSAKey,$HashAlgo,$RSASigPadding)

# Add Basic Constraints
$BasicConstraints = [System.Security.Cryptography.X509Certificates.X509BasicConstraintsExtension]::new($false,$false,0,$false)
$BCExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($BasicConstraints,$false)
$Certificate.CertificateExtensions.Add($BCExtension)

# Add Subject Key Identifier extension
$SubjectKeyIdentifier = [System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension]::new($Certificate.PublicKey,$false)
$SKIExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($SubjectKeyIdentifier,$false)
$Certificate.CertificateExtensions.Add($SKIExtension)

# Add Key Usage
$KeyUsageFlags = [System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::DigitalSignature -bor [System.Security.Cryptography.X509Certificates.X509KeyUsageFlags]::KeyEncipherment
$KeyUsage = [System.Security.Cryptography.X509Certificates.X509KeyUsageExtension]::new($KeyUsageFlags,$true)
$KUExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($KeyUsage,$true)
$Certificate.CertificateExtensions.Add($KUExtension)

# Add EKU
$ServerAuthentication = [System.Security.Cryptography.Oid]::New("Server Authentication")
$EKUOidCollection = [System.Security.Cryptography.OidCollection]::new()
$EKUOidCollection.Add($ServerAuthentication) | out-null # this outputs 0
$EnhancedKeyUsage = [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]::new($EKUOidCollection,$false)
$EKUExtension = [System.Security.Cryptography.X509Certificates.X509Extension]::new($EnhancedKeyUsage,$false)
$Certificate.CertificateExtensions.Add($EKUExtension)

# Add SAN
$SubjectAlternateNameBuilder = [System.Security.Cryptography.X509Certificates.SubjectAlternativeNameBuilder]::new()
$SubjectAlternateNameBuilder.AddDnsName("$($ComputerName).$($Domain)")
$Certificate.CertificateExtensions.Add($SubjectAlternateNameBuilder.Build())

标签: powershellcertificatessl-certificatex509certificate2pki

解决方案


推荐阅读